How to compile a 64-bit dll written in C? - c

I have a Java program which makes use of some native function calls to speed up video encoding. It requires a DLL, which I will write in C (I have just a test one right now).
When I compile the DLL with cl /I "java-path/include" /"java-path/include/win32" -DL -ML Main.c -FeTest.dll it compiles, but I get a 32-bit DLL. After I did some research on the internet, I found out that I would need a 64-bit DLL instead.
After more research, I have found this post which is the only one for C (even C++ was hard to find), but this only works if you are writing/building via Visual Studio 2010. I am using Elipse for the Java, CLion for the C, and compiling via the "Developer Command Prompt." so this does not work for me. How might I recompile as a 64-bit DLL?
EDIT: I am using the cl.exe that comes with Visual Studio 2017
UPDATE: I found the 64-bit cl.exe under C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\Hostx64\x64\cl.exe, however when running it, I get an error that the library machine type (x86) conflicts with the target type (x64). How do I change the library machine type?

As I explained at the beginning of [SO]: How to build a DLL version of libjpeg 9b? (#CristiFati's answer) (bullets from 1. Prepare the ground section), there are different ways to deal with building from command line in VStudio. I'm going to focus on vcvarsall.bat. More details on [MSDN]: Setting the Path and Environment Variables for Command-Line Builds (It's VStudio2015 as VStudio2017 link is broken). I prepared a dummy example.
code.c:
#include <stdio.h>
#include "jni.h"
__declspec(dllexport) int func() {
JavaVMInitArgs args;
printf("Pointer size: %lld bits\n", sizeof(void*) * 8);
printf("JNI_GetDefaultJavaVMInitArgs returned: %d\n", JNI_GetDefaultJavaVMInitArgs(&args));
return 0;
}
Build:
e:\Work\Dev\StackOverflow\q050164687>"c:\Install\x86\Microsoft\Visual Studio Community\2017\VC\Auxiliary\Build\vcvarsall.bat" amd64
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.6.6
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
e:\Work\Dev\StackOverflow\q050164687>dir /b
code.c
e:\Work\Dev\StackOverflow\q050164687>cl /nologo /LD /I"c:\Install\x64\Oracle\Java\jdk1.8.0_152\include" /I"c:\Install\x64\Oracle\Java\jdk1.8.0_152\include\win32" /DWIN64 /DWIN32 code.c /link /LIBPATH:"c:\Install\x64\Oracle\Java\jdk1.8.0_152\lib" /OUT:dummy.dll jvm.lib
code.c
Creating library code.lib and object code.exp
e:\Work\Dev\StackOverflow\q050164687>dir /b
code.c
code.exp
code.lib
code.obj
dummy.dll
Notes:
My vcvarsall path is custom, because I installed VStudio2017 under "C:\Install\x86\Microsoft\Visual Studio Community\2017". Default path is "%SystemDrive%\Program Files (x86)\Microsoft Visual Studio\2017\Community"
After running vcvarsall, I don't have to specify to cl.exe (or link.exe):
The full path
Build options (architecture specific, including paths)
I still have to specify things that it doesn't know about (like Java stuff)
In order to test the newly built .dll, I'm going to use Python, as it's easier than writing another .c program that uses it
Since I linked the .dll to jvm.lib, at runtime it will need jvm.dll, so I'm adding its path into %PATH%
I built my code with VStudio2017 (VCRuntime14.0), but jvm.dll is linked to VCRuntime10.0 (VStudio2010), meaning that there will be (at least) 2 VCRuntimes loaded in my program. That is to be avoided as it could lead to all kinds of nasty problems
e:\Work\Dev\StackOverflow\q050164687>set PATH=%PATH%;c:\Install\x64\Oracle\Java\jdk1.8.0_152\jre\bin\server
e:\Work\Dev\StackOverflow\q050164687>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe"
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> dummy = ctypes.CDLL("dummy.dll")
>>> dummy.func()
Pointer size: 64 bits
JNI_GetDefaultJavaVMInitArgs returned: -1
0
>>>

Related

copying c code from replit to visual studio on mac

So I went to copy my c code from replit to visual studio because I have to work on an assignment online.
I have a floating.h file I created for functions like toDouble(unsigned int) etc. when I include the file in my main.c and call the code, output says “_toDouble” are undefined symbols for architecture x86_64.
My actual implementation of the functions are in my floating.c file.
My floating.h has for example
“double toDouble(struct floating f)”

how can i fix windows c_api error with tensorflow.dll?

I tried to compile on windows c program with tenserflow c api and tenserflow.dll from https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.12.0.zip founded on https://www.tensorflow.org/install/lang_c.
This example:
#include <stdio.h>
#include <tensorflow/c/c_api.h>
int main() {
printf("Hello from TensorFlow C library version %s\n", TF_Version());
return 0;
}
Compiling is success, but when i have run it, i recieved a mistake that libtenserflow.so not found. Its look like that tensorfow,dll from https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.12.0.zip was builded with some mistakes for windows sistem, becaurse libtensorflow.so is a target for Linux.
Can you explain or fix this?
I guess it looks for tensorflow.so because you were using GCC tools on VS Code's WSL mode (or other IDEs). But in order to load DLL you need to have Visual Studio.
Here's a simple process to run the Tensorflow for C demo:
Create a new project in Visual Studio;
Configure the project properties(assume the Tensorflow path is C:\tensorflow\; replace it with yours):
C/C++ > General > Additional Include Directories, add "C:\tensorflow\include\"
Debugging > Environment, add "PATH=C:\tensorflow\lib\;%PATH%"
Don't forget the "PATH=" before your tensorflow.dll path.
Compile and run.
You may also add the Tensorflow path to system environment (replace C:\tensorflow\ with your path):
SET PATH=%PATH%;C:\tensorflow\lib\
P.S. If you don't like the Visual Studio IDE and prefer to use Tensorflow with command line mode, try Bazel for Windows instead.

Use GCC as the Default MEX Compiler for MATLAB 2014a on a 64 bit Windows 7 machine

I am looking for a simple way to compile Unix MEX files on a Windows 7 computer.
The MEX files compile smoothly in MATLAB 2014a on Mac OS X 10.9 (using "XCode with Clang" as the compiler). Some of the people that I work with, however, are having trouble compiling them in Windows 7 using the C compiler from the Windows 7.1 SDK.
I understand that I might be able to avoid these errors if I use GCC to compile MEX files in MATLAB. I am wondering if anyone knows how. I am happy to download and edit whatever files are necessary so that I can a) compile MEX files within MATLAB by using the "MEX" command and b) guarantee that "-I" and "-L" instructions will also passed to the MEX compiler.
Note, my issue is very similar to this post from 2+ years ago. That said, I have put up a new post since a) MATLAB/MinGW/MEX have all had significant updates since then (not even sure if MinGW is the easiest way out of this mess); b) there is a 64 bit thing (not sure if it's a problem) and c) the "-I" and "-L" options are important.
Start by downloading MinGW-w64 compiler toolchain. We'll be using the x64 version. Here's the link to the latest binaries as of this moment (GNU GCC 4.9.1).
Extract the 7z archive to some location (preferably without spaces), say C:\MinGW-w64\mingw64.
Add the bin folder to your PATH environment variable, so something like set PATH=C:\MinGW-w64\mingw64\bin;%PATH% but do it system-wide.
Create the following file (feel free to add compiler switches like -std=c++11 if you want C++11 support):
mexopts_mingw64.bat
#echo off
set MATLAB=%MATLAB%
set MW_TARGET_ARCH=win64
set MINGWROOT=C:\MinGW-w64\mingw64
set PATH=%MINGWROOT%\bin;%PATH%
set COMPILER=x86_64-w64-mingw32-g++
set COMPFLAGS=-c -m64 -mwin32 -mdll -Wall -DMATLAB_MEX_FILE
set OPTIMFLAGS=-DNDEBUG -O2
set DEBUGFLAGS=-g
set NAME_OBJECT=-o
set LINKER=x86_64-w64-mingw32-g++
set LIBLOC=%MATLAB%\extern\lib\%MW_TARGET_ARCH%\microsoft
set LINKFLAGS=-shared -L"%LIBLOC%" -L"%MATLAB%\bin\%MW_TARGET_ARCH%"
set LINKFLAGSPOST=-lmx -lmex -lmat
set LINKOPTIMFLAGS=-O2
set LINKDEBUGFLAGS=-g
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
set RC_COMPILER=
set RC_LINKER=
Now we use it to compile a sample MEX-file:
>> mex -f mexopts_mingw64.bat -v -largeArrayDims "C:\Program Files\MATLAB\R2014a\extern\examples\mex\yprime.c"
>> yprime(1,1:4)
ans =
2.0000 8.9685 4.0000 -1.0947
Note: If you are compiling C++ code and you want to distribute the binaries to other people, you might need to also include a couple of DLL files from MinGW which will be dependencies for the compiled MEX-file (stuff like libstdc++). Use Dependency Walker tool to list them all.

Microsoft linker spontaneously creating library

I'm trying to compile a C program (specifically, the Python interpreter) as a plain statically linked 64-bit Windows binary. My command line looks like this:
cl /DPy_BUILD_CORE ... /link Advapi32.lib Shell32.lib User32.lib
where ... is the long list of source files and include directory specifications, and the library specifications I added as necessary to fix unresolved symbol errors. I'm getting linker output that looks like (after the C compiler has finished running):
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:getbuildinfo.exe
Advapi32.lib
Shell32.lib
User32.lib
getbuildinfo.obj
(lots more .obj's)
Creating library getbuildinfo.lib and object getbuildinfo.exp
... and then a weird error that I'm still trying to figure out, but maybe I might have a better chance if I understand another aspect of the behavior of the linker here.
Why is it creating a library? I didn't tell it to do that. It's only supposed to be creating a .exe.
In particular, I tried a small test case with just a couple of trivial C source files and otherwise the exact same command line, and it behaved as expected, creating only the .exe and not trying anything with libraries. The only differences are in the number and contents of the C source files, but I wouldn't have thought the contents of a C source file could change the behavior of the linker.
What am I missing?

How do I compile a Window API program using cl?

I am trying to compile a simple C Windows API program using the Windows SDK Command Prompt.
Here an excerpt from the program:
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
[...]
RegisterClass(&wc);
hwnd = CreateWindow("test", NULL, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
[...]
When I compile it using
cl test.c
in the Windows SDK Command Promt, it gives me a lot of linker errors like these:
test.obj : error LNK2019: unresolved external symbol __imp_CreateWindowExA referenced in function WinMain
test.obj : error LNK2019: unresolved external symbol __imp_RegisterClassA referenced in function WinMain
There are at least two problems.
The linker is telling you that there is an "unresolved external symbol". That means it can't find a definition for the function(s) that you tried to call. In this case, there are two such undefined functions: CreateWindowExA and RegisterClassA.
Obviously the definition for those functions is not to be found in your code, but rather in the Windows API libraries, so you'll need to inform the linker of where it can find those definitions.
The SDK comes with stubs (*.lib) files, which contain information used by the linker so that it can find the proper function definitions in the Windows DLLs at runtime. You need to instruct the linker where it can find those *.lib files.
There are a couple of different strategies for doing so:
The simple (albeit non-portable) way is to insert a #pragma statement into your source file that instructs the compiler to leave a comment recognized by the linker. For example,
#pragma comment(lib, "user32")
automatically links to user32.lib, which is the stub file for user32.dll.
Alternatively, you can pass the parameters on the command line to cl.exe. This gets awfully complicated in a hurry, though, if you're not using MSBuild or some kind of make file. In this case, you would need to modify your command line to (at minimum):
cl test.c user32.lib
Both of these options naturally assumes that your Windows SDK directory was added to the path. I'm pretty sure the installer does that for you automatically, but I'm not positive. If it doesn't, or you've removed these files from your path, you'll need to use fully-qualified paths to the *.lib files on the command line.
Reading the documentation for the possible compiler options is a good place to start. Or better yet, if you're unfamiliar with Windows programming, using an environment like Visual Studio that puts all of this stuff together for you automatically. Once you understand what's going on, look to see what the command line that Visual Studio runs is, and dissect it bit-by-bit.
Next problem is that you're compiling without Unicode defined, and because ANSI is the default, all of the macros inside the Windows header files are resolving to call the A suffixed versions of all the SDK functions. This is probably not what you want. Windows has been fully Unicode now for over a decade, and all new applications should be built as Unicode. The Unicode versions have a W suffix appended to their name.
Again, you can instruct the compiler to build with Unicode explicitly by either adding lines to your source file, or adding parameters to your command line.
In this case, the simplest way is probably just to add
#define UNICODE
to the top of your source file before #include <windows.h>. Just as we saw above, from the Visual Studio environment, UNICODE is automatically defined for you unless you explicitly change your project settings to target something else.
Those functions live in user32.lib. You need to supply that to the cl tool.
cl test.c ""C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\user32.lib"
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.307
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\user32.lib"

Resources