Compiling 64 bit DLL for JNI - c

I want to include a C library in my Java project via JNI. I wrote the necessary JNI wrapper code and I have compiled and tested it in a Linux environment using gcc and make. Now I need to compile this to make a 64 bit Windows DLL, and I cannot get it to compile.
I downloaded Visual C++ Express 2010 and I have been using cl.exe on the command line. In the absence of knowing any better way to do it, I have just called cl.exe with all of the files I want to compile as arguments. I get a variety of errors:
Command line warning D9024: unrecognized source file type 'svm_jni.h'...
and
svm_jni.c(63) : error C2275: 'jobject' : illegal use of this type as an expression...
The first problem I have discovered is do to the fact that cl.exe does not accept .h files (I guess its only meant for C++ instead of C?). Is there a workaround for this? I could change all of the .h files to .c files and change the include statements, but I would prefer not to do this.
I have tried compiling using make and gcc on MinGW, but it always says that it cannot compile to a 64 bit target.
I have tried doing things through VC++ using the makefile project type, but I could not figure out how that works.
Any suggestions?
EDIT: I removed the .h files from the command line arguments and that solves part of the problem. I have been using
-I "C:\Program Files\Java\jdk1.6.0_21\include" -I "C:\Program Files\Java\jdk1.6.0_21\include\win32"
to get jni.h and jni_md.h. I still get
svm_jni.c(63) : error C2275: 'jobject' : illegal use of this type as an expression
C:\Program Files\Java\jdk1.6.0_21\include\jni.h(83) : see declaration of 'jobject'
and a bunch of syntax and weird errors after that. I am assuming all the errors are the result of a common problem, but I don't know whats going wrong.
Is there a 64 bit version of jni_md.h? The one I'm using now is in \include\win32

You don't really want to compile the header files, rather you want to include them in your compilation path when you compile the c/c++ files.
As for the jobject issue, you need to include the jni header files which are located under the %JAVA_HOME%\include directory.
For Visual C++ Express, did you download the 64 bit building tools? And when you state that gcc and MinGW cannot compile to a 64 bit target, what message are you getting exactly? Do you have minGW-w64?

Related

Multible definitions including open source library (with seemingly correct linker settings?)

Im working on a program for my studies, that uses an open source library. It is meant to run on Raspberry Pi (Raspbian Kernel). Because of my intention to be also able to load it on a PLC i used mostly pure C. The Library itself comes with suitable header and .c files.
When i use the pre installed GCC compiler on the Raspberry my program compiles without any errors and works fine. Now here comes my problem:
I tried to get this projekt to work on windows using code::blocks IDE with MinGW installed. I revisited the library and downloaded the zip for windows (apperently same header and .c file, but also .lib and .dll included).
I set the search directories and linker settings within the project and included the header as usual with #include "header.h" for the relative path. It doesn't compile and gives alot multible definition and first defined here which usually indicate wrong linking and inclusion.
As i tried to identify some of this definitions i noticed that the functions which cause errors are defined one time in the library.c file. At the beginning of this .c file it also includes the header one time.
Short summary:
This works with raspbian GCC:
$ gcc -sdt=c99 main.c library.c -o executable
but gives errors with Windows IDE + MinGW
Am i missing something serious? The dynamic link lib should only be used by the executable afterwards. I thought maybe the libraby.c gets replaced by the library.lib but if i remove one of them the project doesn't know the functions. I also searched for wrong inclusions. I'm really at the end of my knowledge here, and also searched for posts that would help me, but those were mostly "where is the linker path" or "inclusion of .c files". It seems so an simple problem which i overlooked.
Any help Would be appriciated. I will supply more details if needed.
Thanks!
Edit (2):
obj\Debug\open62541.o:open62541.c:(.text+0x3152a): undefined reference to `__imp_shutdown'
obj\Debug\open62541.o:open62541.c:(.text+0x3153f): undefined reference to `__imp_closesocket'
obj\Debug\open62541.o:open62541.c:(.text+0x315a7): undefined reference to `__imp_send'
obj\Debug\open62541.o:open62541.c:(.text+0x315b9): undefined reference to `__imp_WSAGetLastError'
.....
Edit (3)
Answer 1!
Compiled good now, thanks everyone.
It looks like your library is open62541.
There are two ways to include the library in your source:
Build a shared/static lib and link it to your code
Enable Amalgamation which generates a single .c and .h file which you can directly compile with your code
You are combining both methods on mingw which adds the whole library two times.
Probably you only want to link the .c file without the .lib, thus your compile command should look something like this:
gcc -sdt=c99 main.c open62541.c -o test
Additionally, since open62541 needs the ws2_32 library on windows, the compiler should be called with:
gcc -std=c99 main.c open62541.c -o test -lws2_32

Having issues compiling an exploit using GCC

I was trying to compile a C exploit for a security class I'm in and was struggling to get GCC to perform. The issue is that my /usr/include folder is missing folders that GCC is looking for to handle the includes of the file. The first error below describes a folder that doesn't exist.
asm/page.h: No such file or directory
What I've tried so far:
Symlink it with my /usr/src/linux-headers-4.4.0-kali1-common/include/* folders, but files within that folder start throwing errors that they in turn can't find other files.
Using GCC's -I parameter to manually specify each folder to look in for my includes but this also doesn't work. (Below)
gcc 10613.c -o workdamnit-I/usr/src/linux-headers-4.4.0-kali1-common/include/asm-generic/ -I/usr/src/linux-headers-4.4.0-kali1-common/include/linux/ -I/usr/src/linux-headers-4.4.0-kali1-common/include/uapi/asm-generic/ -I/usr/src/linux-headers-4.4.0-kali1-common/include/uapi/linux/
ERROR: In file included from /usr/include/stdio.h:33:0,
from 10613.c:2:
/usr/src/linux-headers-4.4.0-kali1-common/include/linux/stddef.h:4:31: fatal error: uapi/linux/stddef.h: No such file or directory
compilation terminated.
I updated the import statement to use page.h from my kali linux common headers. When I tried to run this, I received the below error:
'PAGE_SIZE' undeclared (first use in this function).
Lastly, I tried to compile with wine gcc but this particular exploit uses a socket library that I guess can't be compiled on a windows machine.
GCC version: 5.3.1
Link to exploit: https://www.exploit-db.com/exploits/10613/
My knowledge of C and its compilation requirements is very limited. Any assistance would be greatly appreciated.
Please give a usable and compilable example: https://stackoverflow.com/help/mcve
Based on the errors, it looks like -I/usr/src/linux-headers-4.4.0-kali1-common/include/uapi/linux/ should actually probably be -I/usr/src/linux-headers-4.4.0-kali1-common/include.

Trouble linking a mex file to static mpfr library

I am trying to compile a mex file that requires the mpfr C library, using MATLAB R2013a on Mac OS 10.8.5. I would like it to run on systems that don't have a separate installation of MPFR, so I am trying to include the static library:
mex my_program.c libmpfr.a
I copied the libmpfr.a library into the folder with my source code to simplify things. When I run this command I get the following error message:
ld: targeted OS version does not support use of thread local variables in _mpfr_add for architecture x86_64
A little research suggested that this issue could be due to a problem with the llvm-gcc-4.2 compiler that comes with Xcode and is used in MATLAB by default. So, I tried to set up a different compiler. I got GCC 4.7.4 (the latest version supported by MATLAB) from MacPorts, as described here: http://www.ficksworkshop.com/blog/14-coding/65-installing-gcc-on-mac. Next, I edited the mexopts.sh file to point MATLAB to the correct compiler, by entering the following settings:
CC='/opt/local/bin/gcc-mp-4.7'
CXX='/opt/local/bin/g++-mp-4.7'
Now when I try to compile, I get a different error message:
In file included from /Applications/MATLAB_R2013a.app/extern/include/matrix.h:294:0,
from /Applications/MATLAB_R2013a.app/extern/include/mex.h:58,
from include/main.h:5,
from include/poisson.h:7,
from src/main.c:22:
/Applications/MATLAB_R2013a.app/extern/include/tmwtypes.h:61:21: fatal error: float.h: No such file or directory
If, in mexopts.sh, I additionally set
SDKROOT='/opt/local/'
or a number of other choices (based on the locations of different copies of float.h that I can find on my system), I instead see
my_program.c:10:20: fatal error: stdlib.h: No such file or directory
So it seems that GCC-MP-4.7 is having trouble locating all of the standard C libraries.
I'd be grateful for a solution to either of these issues (linking to static mpfr useing the default compiler, or configuring GCC 4.7 to find the standard C libraries).
I found that the "thread local variables" error was caused by the compiler trying to include backwards-compatibility to OSX 10.5. Since I don't need it to do this, I edited the mexopts.sh file, replacing this line
MACOSX_DEPLOYMENT_TARGET='10.5'
with this:
MACOSX_DEPLOYMENT_TARGET='10.8'
This resulted in the mex file compiling successfully using the built-in Xcode compiler.

Statically Linking glib

I'm trying to statically link glib into my C program. I'm not sure what's the best way to do this. I downloaded the code and put it in a subdirectory called glib-2.36.4. I added "-Iglib-2.36.4" when using gcc. The glib.h is in the glib-2.36.4/glib directory and in that file there are references to other header files under the glib directory (such as #include ).
I'm not sure why that is since both glib.h and these other header files are at the same level (in glib subdirectory). I got a compile error due to galloca.h not being found (even though it's there). So I copied glib.h up one level and those errors went away. I then got an error about a missing glibconfig.h. I copied that from my usr directory and that error went away. I compiled my project and now I'm getting an error about undefined reference to g_ptr_array_new. I guess this must be because I haven't actually compiled glib. I had tried to build glib, but when I typed "./configure", but I got this message:
checking if arpa/nameser_compat.h is needed... configure: error: could not compile test program either way
I did install glib using yum, but I really want this code to run even if glib is not installed on a machine.
You need to install both glib and glib-dev via yum, compile using ./configure, (take a look in the ./configure script to see if there are any flags you need to supply or defines you need to produce the static build), without moving any files about, and then you need to compile your code using -i path/to/glib/includes and link with -L path/to/built/static/library

Skipping incompatible zlib dll

Situation:
I have many gzipped input files that I want to process in a c program. I can extract each of them each time i need them but this takes a lot of time, so I would like to use in memory extraction. As a test case i downloaded the zlib sources from http://zlib.net/ and tried to compile the example zpipe.c
Problem:
When I compile zpipe.c using:
x86_64-w64-mingw32-gcc -Wall -O3 zpipe.c -o zpipe -L. -lzlib1
I get the error:
x86_64-w64-mingw32/bin/ld.exe: skipping incompatible ./zlib1.dll when searching for -lzlib1
x86_64-w64-mingw32/4.5.4/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lzlib1
What I think is the problem (I got this from Skipping incompatible error when linking)
I try to link a 32 bit dll while I compile in 64 bit code. When i look at http://zlib.net/zlib_faq.html#faq26 it is said that zlib is tested on 64 bit machines, but I guess this means you still compile 32 bit code. Note that I compile zpipe.c (provided in the zlib source), so i'm sure the inclusions are all ok. I put the zlib1.dll in the compilation directory.
What did I do/find:
Among others I found 2 good examples (however with both of them I have the problem described above)
http://www.codeguru.com/cpp/cpp/algorithms/compression/article.php/c11735
http://bobobobo.wordpress.com/2008/02/23/how-to-use-zlib/
And I looked at other questions, such as:
Trying to compile program that uses zlib. Link unresolved error
Skipping Incompatible Libraries at compile
I also build a dll myself in vc 2010, however, all project configurations in the zlib 1.26 source are for a 32 bit configuration. So after I build a dll, I have the same error as above.
A long story so a quick summary of my questions:
Is there something I do wrong during compilation?
Is it correct that I will never be able to use the zlib1 dll when I compile in 64 bit?
And most important: Can I somehow compile a 64 bit version of zlib myself (using for example these http://msdn.microsoft.com/en-us/library/9yb4317s.aspx instructions), or are these already available somewhere (I was not able to find these until now)?
Thank you all for your time!
You can most definitely compile a 64-bit version yourself. Open your DLL-project in Visual Studio, go into the configuration manager and create a new configuration for 64-bit. The instructions you linked should be fine.
If you are having problem with this you can also include the source of zlib in your application instead of linking against the DLL.

Resources