MSVC programs calling an MinGW DLL - c++

Following this short tutorial, I get stuck at the stage of linking the DLL built by MinGW. Here are the two simple source code files I use for practice purpose.
foo.cpp for foo.dll
const char *greeting(void)
{
return "Hello, World!";
}
main.cpp for main.exe
#include <cstdio>
const char * greeting(void);
int main(int argc, char *argv[])
{
std::printf("%s\n", greeting());
return 0;
}
I ran all the commands in MSYS2 on Windows 10. Below is the commands and their outputs. It looks time-wasting long, but really only the last 2 lines matter.
### Generate foo.def and foo.dll.
$ g++ foo.cpp -shared -Wall -Wl,--output-def=foo.def -o foo.dll
$ cat foo.def
EXPORTS
_Z8greetingv #1
### Generate foo.lib and foo.exp.
$ lib /machine:x64 /def:foo.def
Microsoft (R) Library Manager Version 14.27.29112.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library foo.lib and object foo.exp
### Try to generate .exe file.
$ cl main.cpp foo.lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29112 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
Microsoft (R) Incremental Linker Version 14.27.29112.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
"/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\lib\x64"
"/LIBPATH:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64"
"/LIBPATH:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x64"
main.obj
foo.lib
main.obj : error LNK2019: unresolved external symbol "char const * __cdecl greeting(void)" (?greeting##YAPEBDXZ) referenced in function main
main.exe : fatal error LNK1120: 1 unresolved externals
As you can see, the last 2 lines is the problem. It will work, if change the calling convention with extern "C". So, apparently something went wrong with this mysterious calling convention stuff. I'm new to MSVC toolset by the way. So, maybe this is a stupid question. Any hint? Thanks.
EDIT: Please note that the codes above are supposed to be compiled as C++ codes instead of C codes. They look simple and, of course, there isn't any object-oriented code in them. They are just an experiment, but I'm planing to put C++ classes into .dll file if it's doable. Therefore, I'm wondering if it's still possible when name mangling is taken into account.

Related

How to use the C++ standalone ASIO library

I am trying to use the asio library on Windows 10, here is a simple test code block:
#include <iostream>
#include <asio.hpp>
using std::cout;
int main()
{
std::cout << "hello asio\n";
asio::io_context ioc;
asio::steady_timer tmer(ioc, asio::chrono::seconds(1));
tmer.wait();
cout << "hi asio\n";
ioc.run();
return 0;
}
with Visual Studio 2017. To open a developer command prompt, I use the following command
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools>vsdevcmd
Then, based on the asio doc, I run the command nmake -f Makefile.msc under the asio src folder. But I am getting an error:
Microsoft (R) Program Maintenance Utility Version 14.16.27025.1
Copyright (C) Microsoft Corporation. All rights reserved.
cl -Fetests\latency\tcp_client.exe -Fotests\latency\tcp_client.obj -nologo -EHac -GR -I. -I../include -O2 -MD -I../../boost_1_34_1 -D_WIN32_WINNT=0x0501 -DBOOST_ALL_NO_LIB -DBOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING tests\latency\tcp_client.cpp -link -opt:ref
tcp_client.cpp
../include\asio/detail/config.hpp(26): fatal error C1083: Cannot open include file: 'boost/config.hpp': No such file or directory
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x86\cl.EXE"' : return code '0x2'
Stop.
It seems the library requires boost/config.hpp. I really trying to avoid to use the boost. Is there a way I could use the asio standalone on windows 10?
To use asio without any boost libraries, you have to define ASIO_STANDALONE at some point. The best would be in your Visual Studio project, or in your code before any include of asio header.
I tried to use vcpkg, but it turns out I only need to download the library and create a cmake file to do the job.
cmake_minimum_required(VERSION 3.12)
project(asio)
add_definitions(-DASIO_STANDALONE -D_WIN32_WINNT=0x0501)
# -DBOOST_DATE_TIME_NO_LIB -DBOOST_REGEX_NO_LIB)
# include_directories(${VCPKG_DIR}//asio_x86-windows//include)
include_directories(./../libs/asio-1.12.2/include)
add_executable(asio s5.cpp)
Following command line seems to work. It would be nice addition to boost.asio standalone documentation.
$ nmake STANDALONE=1 -f Makefile.msc
I took me some time to figure out this since I have never used NMAKE even though I have developed a lot of stuff to Windows with MS compiler. It is very not-so-good tool for MAKE process.
Although the make command just executes tests. No lib is generated. Just include headers...

Unresolved external symbols when linking to CUDA [duplicate]

I have tried basically everything and I can't get vs2013 to compile and link against the cusolver library. I have tried all the sample projects that came with the cuda installation package and basically all of the samples work fine. Though there are no samples using cusolver. The include files work just fine. The linker is in error and all of the other cuda stuff links just fine. I tried adding one line of cusolver code to a perfectly working cuda sample and it breaks. Here is the code snippet:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "cusolver_common.h"
#include "cusolverDn.h"
#include <stdio.h>
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
__global__ void addKernel(int *c, const int *a, const int *b)
{
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
int main()
{
cusolverDnCreate(new cusolverDnHandle_t);
return 0;
}
The build output is:
1>------ Build started: Project: The cudan, Configuration: Release x64 ------
1> Compiling CUDA source file kernel.cu...
1>
1> c:\Users\Gdizzle\documents\visual studio 2013\Projects\The cudan\The cudan>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\bin\nvcc.exe" -gencode=arch=compute_20,code=\"sm_20,compute_20\" --use-local-env --cl-version 2013 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\include" --keep-dir x64\Release -maxrregcount=0 --machine 64 --compile -cudart static -DWIN32 -DWIN64 -DNDEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MD " -o x64\Release\kernel.cu.obj "c:\Users\Gdizzle\documents\visual studio 2013\Projects\The cudan\The cudan\kernel.cu"
1> kernel.cu
1>kernel.cu.obj : error LNK2001: unresolved external symbol cusolverDnCreate
1>c:\users\gdizzle\documents\visual studio 2013\Projects\The cudan\x64\Release\The cudan.exe : fatal error LNK1120: 1 unresolved externals
I've tried adding directories in project properties -> vc++ and in linker options and that didn't help. Any ideas? It's so weird that this 1 Library doesn't work.
(Also if you have any other ideas on how to solve a systems of equations with least squares using gpu programming that would be helpful)
EDIT UPDATE: You must not include extra .h files nor extra libs by adding additional libraries or additional include directories in other linker options like cudaLinker or vc++ directories
I've just tested this on Windows 7 64-bit, Visual Studio 2013 Community, CUDA 7.
start by opening the vectorAdd cuda sample code. Be sure you can build this code correctly. (It should be a x64 project. CUDA 7 does not support 32-bit projects or operating systems on windows.) If you can't build this correctly, your issue has nothing to do with cusolver
Add the following header file at the top of vectorAdd.cu:
#include <cusolverDn.h>
Add the following two lines to the beginning of the main routine:
cusolverDnHandle_t my_handle;
cusolverDnCreate(&my_handle);
Go to Project...vectorAdd Properties...Linker...Input...Additional Dependencies. In this field you should already find a number of libraries including cudart_static.lib. Click in this field, then click on the drop-down menu arrow on the right, then click on <Edit...> At the bottom of the list of libraries in the edit window, add cusolver.lib on its own line.
Rebuild the project.

/Fe (Name EXE File) is not working

I would like to compile a cpp source file in windows 7, visual studio 2010 using
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
When I do the following
>cl /EHs main.cpp -o test
I got
cl : Command line warning D9035 : option 'o' has been deprecated and will be removed in a future release
Ok fair enough. I've checked this page /Fe (Name EXE File). This option is not working with me.It gives me this error
cl : Command line warning D9024 : unrecognized source file type 'test', object file assumed
main.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
test
LINK : fatal error LNK1181: cannot open input file 'test.obj'
Now how should I activate this option? I always find it difficult to read MSDN Library. It is not friendly at all.
Note that there is no space between /Fe and the file name.
cl /EHs /Fetest.exe main.cpp
Alternatively, you can use the colon syntax:
cl /EHs /Fe: test.exe main.cpp
You can achieve same thing using
cl /Ehs main.cpp /link /OUT:test.exe
/link tells cl to pass these options to linker and /OUT specifies the name of output file.

Which compilation options should I use to link with Boost using cl.exe?

I have a program which I would like compile using cl.exe on the command-line. This program depends on some boost libraries which I fail to link to.
The error I'm getting is:
cl /Fosamples\proxy\proxy.obj /c samples\proxy\proxy.cpp /TP /O2 /EHsc
/DBOOST_ALL_NO_LIB /DBOOST_THREAD_USE_LIB /DBOOST_SYSTEM_USE_LIB
/DBOOST_USE_WINDOWS_H /DTAP_ID=\"tap0901\" /D_WIN32_WINNT=0x0501 /MD /nologo
/Isamples\proxy /Iinclude proxy.cpp
link /nologo /MD /OUT:samples\proxy\proxy.exe /LIBPATH:samples\proxy
/LIBPATH:lib asiotap.lib libboost_system-vc100-mt-1_47.lib
libboost_thread-vc100-mt-1_47.lib ws2_32.lib gdi32.lib iphlpapi.lib
advapi32.lib samples\proxy\proxy.obj
LINK : warning LNK4044: unrecognized option '/MD'; ignored
asiotap.lib(bootp_builder.obj) : error LNK2001: unresolved external
symbol "class boost::system::error_category const & __cdecl
boost::system::system_category(void)"
(?system_category#system#boost##YAAEBVerror_category#12#XZ)
I compiled Boost, using the following command-line, from the x64 MSVC command prompt:
.\b2.exe install toolset=msvc --prefix=C:\Boost-VC-x64
If I look inside libboost_system-vc100-mt-1_47.lib I can see that:
?system_category#system#boost##YAABVerror_category#12#XZ
Is exported. But If you look closely it differs a bit from the one in my compilation errors:
?system_category#system#boost##YAAEBVerror_category#12#XZ // The symbol I miss
?system_category#system#boost##YAABVerror_category#12#XZ // The exported symbol
I guess I should either change Boost or my compilation options but fail to figure what to change exactly. Any clue ?
Thank you very much.
After some investigations, I realized that I compiled Boost for a x86 platform where I was linking with a x64 binary.
I thought that compiling Boost inside a Visual Studio x64 command prompt was enough but you actually have to specify:
.\b2.exe install toolset=msvc address-model=64 --prefix=C:\Boost-VC-x64
To make it work.

How to link against a static library which uses static libraries itself using scons and Visual C++?

My SConstruct file looks something like this:
jnglLibs = Split("freetype png ogg vorbisfile") # left out a few
env.Library(target="jngl", source=source_files, LIBS=jnglLibs)
env.Program("test.cpp", LIBS=Split("jngl") + jnglLibs)
The static library links fine but the program fails with unresolved external symbols from the libraries in jnglLibs.
lib /nologo /OUT:jngl.lib finally.obj freetype.obj main.obj opengl.obj sprite.ob
j tess.obj texture.obj window.obj windowptr.obj callbacks.obj ConvertUTF.obj aud
io.obj win32\message.obj win32\time.obj win32\window.obj
cl /Fotest.obj /c test.cpp /TP /nologo /EHsc /MD -O2 -DNDEBUG /I.
test.cpp
link /OUT:test.exe /LIBPATH:. /LIBPATH:lib jngl.lib freetype.lib png.lib opengl3
2.lib glu32.lib user32.lib shell32.lib gdi32.lib z.lib jpeg.lib dl.lib openal32.
lib alut.lib ogg.lib vorbisfile.lib test.obj
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
jngl.lib(freetype.obj) : error LNK2019: unresolved external symbol FT_Done_FreeT
ype referenced in function "public: __cdecl jngl::Font::~Font(void)" (??1Font#jn
gl##QEAA#XZ)
... and so on
Why doesn't it find the symbol FT_Done_FreeType which is in freetype.lib? It works perfectly with GCC.
There are a lot of quirks with static linking on Windows.. I've had one or two similar problems to this but mostly my problem was once the 'static' libs were compiled they still depended on the .dll's being there. Anyway, I've been feeling your pain for a while now but got through it for my purposes... here's one page that really helped me.
http://xmlsoft.org/XSLT/tutorial2/libxslt_pipes.html#windows-build
It doesn't have to do with those particular libraries you listed but it might give you some clues. One thing is figuring out which C-runtime library each of those .libs (or '_a.libs,' which you might want to look into) were compiled against and make sure they are all the same when you statically link. So since you're using /MD, make sure all those libs were also compiled with /MD and not /MT. That COULD be a reason it isn't finding that freetype symbol, but it's just one guess. Good luck!