使用 MSVC 的 cl 创建 DLL
Creating a DLL using MSVC's cl
我试图了解构建和 linking 的工作原理,因为有一个库我想编译成 DLL。我无法控制将用于编译的工具 - 这将是通过命令行调用的 msvc
工具。
为此,我设法找到了 a tutorial on creating DLLs that does not use Visual Studio。它适用于 mingw
,但我设法让它与 cl
一起使用
我已经成功翻译了部分流程以与 msvc
工具一起使用:
gcc -c -o add.o add.c -D ADD_EXPORTS
被翻译成
cl /c /D ADD_EXPORTS add.c
我无法完全翻译以下行:
gcc -o add.dll add.o -s -shared -Wl,--subsystem,windows
但以下方法有效:
link /DLL /NOENTRY add.obj
并创建了 .exp
、.lib
和 .dll
文件。 -s
开关似乎并不重要(它删除了一些信息,所以我猜最坏的情况是我会得到一个稍大的文件)
然后我设法从 addtest.c
创建了一个 .obj
文件,link 它(针对 .lib
文件),并得到了一个 .exe
只要 dll
将它放在同一个文件夹中,它就可以完美运行。
关于更难的问题:The library I ultimately want to have compiled
在玩弄 #include
s 并四处移动一些文件以确保每个人都能找到他们的 header 之后,我编译了每个源文件(对于 windows - 据我了解,_WIN32
在预处理时自动定义)和我做的一样 add.c
(没有 ADD_EXPORTS
),加上我自己的文件,叫做 Source.cpp
(我没有创建 header为此)
#include "serial/serial.h"
#include <combaseapi.h>
using serial::Serial;
using std::string;
using std::vector;
using serial::PortInfo;
Serial* sp = NULL;
extern "C" {
__declspec(dllexport) bool __cdecl createConnection(const char* port, uint32_t baudrate)
{
try {
sp = new Serial(port, baudrate);
return true;
}
catch (...)
{
return false;
}
}
}
在将它们全部制作成 .obj
文件后,我尝试调用 linker,使用我生成的所有 .obj
文件,使用 link /DLL /NOENTRY Source.obj list_ports/list_ports_win.obj win.obj serial.obj
为此我得到了 134 errors
关于如何在没有 visual studio 的情况下创建 DLL 的信息似乎非常稀缺,而且我找不到任何关于我查找的错误的有用信息(查找时找不到常见错误错误 + 符号)
这里有什么问题?
编辑:感谢一条评论,我设法发现我在 linking 到 CRT 库时遇到问题。 This 帮助我减少了错误的数量,我会看看我是否能弄清楚我得到的新输出并进一步编辑
新 linking 命令:
link /DLL /NOENTRY Source.obj list_ports/list_ports_win.obj win.obj serial.obj /LIBPATH:"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Redist/MSVC/14.29.30036/x64/Microsoft.VC142.CRT"
编辑 2:
使用 cl /c /clr source_file
编译源文件导致 significantly fewer errors 当 link 未指定 LIBPATH
时。我想我什至可以自己解决所有这些问题。稍后我会继续努力。
注意连载最后一个正式版(v1.2.1)发布于2015年4月(20150422),activity 从那以后显着下降。
在继续之前请检查 [SO]: Linking to CRT (unresolved external symbol WinMainCRTStartup) (@CristiFati's answer)(刚刚发布)。
我刚刚构建了包并将工件放在[GitHub]: (master) CristiFati/Prebuilt-Binaries - Prebuilt-Binaries/Serial/v024f80634f40073a41be43e956b5ebaca17f6167(原始代码只构建了一个静态库,我增强它也构建了一个动态库)。按照下载和“安装”说明进行操作。
尝试的方案是从您的源代码构建一个 .dll,它使用下载的 Serial 库。
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\q071859149]> sopr.bat
### Set shorter prompt to better fit when pasted in Whosebug (or other) pages ###
[prompt]> "c:\Install\pc032\Microsoft\VisualStudioCommunity19\VC\Auxiliary\Build\vcvarsall.bat" x64 >nul
[prompt]> dir /b
Source.cpp
[prompt]> set LIBSERIAL_DIR=c:\Program Files\WjwWood\Serial4f80634f40073a41be43e956b5ebaca17f6167
[prompt]> :: Build with static libserial
[prompt]> cl /nologo /I"%LIBSERIAL_DIR%\include" /EHsc /MD /c Source.cpp /FoSource_stat.obj
Source.cpp
[prompt]> link /NOLOGO /DLL /LIBPATH:"%LIBSERIAL_DIR%\lib" Source_stat.obj libserialstatic.lib
Creating library Source_stat.lib and object Source_stat.exp
[prompt]> dir /b
Source.cpp
Source_stat.dll
Source_stat.exp
Source_stat.lib
Source_stat.obj
[prompt]> :: Build with dynamic libserial
[prompt]> cl /nologo /I"%LIBSERIAL_DIR%\include" /EHsc /MD /DLIBSERIAL_DYNAMIC /c Source.cpp /FoSource_dyn.obj
Source.cpp
[prompt]> link /NOLOGO /DLL /LIBPATH:"%LIBSERIAL_DIR%\lib" Source_dyn.obj libserial.lib
Creating library Source_dyn.lib and object Source_dyn.exp
[prompt]>
[prompt]> dir
Volume in drive E is SSD0-WORK
Volume Serial Number is AE9E-72AC
Directory of e:\Work\Dev\Whosebug\q071859149
22/04/15 01:58 <DIR> .
22/04/15 01:58 <DIR> ..
22/04/15 01:50 394 Source.cpp
22/04/15 01:58 17,920 Source_dyn.dll
22/04/15 01:58 704 Source_dyn.exp
22/04/15 01:58 1,778 Source_dyn.lib
22/04/15 01:57 47,856 Source_dyn.obj
22/04/15 01:55 41,472 Source_stat.dll
22/04/15 01:55 707 Source_stat.exp
22/04/15 01:55 1,790 Source_stat.lib
22/04/15 01:55 46,299 Source_stat.obj
9 File(s) 158,920 bytes
2 Dir(s) 24,132,493,312 bytes free
2 个生成的 .dll 之间的“图形”比较。请注意,与 libserial.lib 链接的变体需要 libserial.dll:
我试图了解构建和 linking 的工作原理,因为有一个库我想编译成 DLL。我无法控制将用于编译的工具 - 这将是通过命令行调用的 msvc
工具。
为此,我设法找到了 a tutorial on creating DLLs that does not use Visual Studio。它适用于 mingw
,但我设法让它与 cl
我已经成功翻译了部分流程以与 msvc
工具一起使用:
gcc -c -o add.o add.c -D ADD_EXPORTS
被翻译成
cl /c /D ADD_EXPORTS add.c
我无法完全翻译以下行:
gcc -o add.dll add.o -s -shared -Wl,--subsystem,windows
但以下方法有效:
link /DLL /NOENTRY add.obj
并创建了 .exp
、.lib
和 .dll
文件。 -s
开关似乎并不重要(它删除了一些信息,所以我猜最坏的情况是我会得到一个稍大的文件)
然后我设法从 addtest.c
创建了一个 .obj
文件,link 它(针对 .lib
文件),并得到了一个 .exe
只要 dll
将它放在同一个文件夹中,它就可以完美运行。
关于更难的问题:The library I ultimately want to have compiled
在玩弄 #include
s 并四处移动一些文件以确保每个人都能找到他们的 header 之后,我编译了每个源文件(对于 windows - 据我了解,_WIN32
在预处理时自动定义)和我做的一样 add.c
(没有 ADD_EXPORTS
),加上我自己的文件,叫做 Source.cpp
(我没有创建 header为此)
#include "serial/serial.h"
#include <combaseapi.h>
using serial::Serial;
using std::string;
using std::vector;
using serial::PortInfo;
Serial* sp = NULL;
extern "C" {
__declspec(dllexport) bool __cdecl createConnection(const char* port, uint32_t baudrate)
{
try {
sp = new Serial(port, baudrate);
return true;
}
catch (...)
{
return false;
}
}
}
在将它们全部制作成 .obj
文件后,我尝试调用 linker,使用我生成的所有 .obj
文件,使用 link /DLL /NOENTRY Source.obj list_ports/list_ports_win.obj win.obj serial.obj
为此我得到了 134 errors
关于如何在没有 visual studio 的情况下创建 DLL 的信息似乎非常稀缺,而且我找不到任何关于我查找的错误的有用信息(查找时找不到常见错误错误 + 符号)
这里有什么问题?
编辑:感谢一条评论,我设法发现我在 linking 到 CRT 库时遇到问题。 This 帮助我减少了错误的数量,我会看看我是否能弄清楚我得到的新输出并进一步编辑
新 linking 命令:
link /DLL /NOENTRY Source.obj list_ports/list_ports_win.obj win.obj serial.obj /LIBPATH:"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Redist/MSVC/14.29.30036/x64/Microsoft.VC142.CRT"
编辑 2:
使用 cl /c /clr source_file
编译源文件导致 significantly fewer errors 当 link 未指定 LIBPATH
时。我想我什至可以自己解决所有这些问题。稍后我会继续努力。
注意连载最后一个正式版(v1.2.1)发布于2015年4月(20150422),activity 从那以后显着下降。
在继续之前请检查 [SO]: Linking to CRT (unresolved external symbol WinMainCRTStartup) (@CristiFati's answer)(刚刚发布)。
我刚刚构建了包并将工件放在[GitHub]: (master) CristiFati/Prebuilt-Binaries - Prebuilt-Binaries/Serial/v024f80634f40073a41be43e956b5ebaca17f6167(原始代码只构建了一个静态库,我增强它也构建了一个动态库)。按照下载和“安装”说明进行操作。
尝试的方案是从您的源代码构建一个 .dll,它使用下载的 Serial 库。
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\Whosebug\q071859149]> sopr.bat ### Set shorter prompt to better fit when pasted in Whosebug (or other) pages ### [prompt]> "c:\Install\pc032\Microsoft\VisualStudioCommunity19\VC\Auxiliary\Build\vcvarsall.bat" x64 >nul [prompt]> dir /b Source.cpp [prompt]> set LIBSERIAL_DIR=c:\Program Files\WjwWood\Serial4f80634f40073a41be43e956b5ebaca17f6167 [prompt]> :: Build with static libserial [prompt]> cl /nologo /I"%LIBSERIAL_DIR%\include" /EHsc /MD /c Source.cpp /FoSource_stat.obj Source.cpp [prompt]> link /NOLOGO /DLL /LIBPATH:"%LIBSERIAL_DIR%\lib" Source_stat.obj libserialstatic.lib Creating library Source_stat.lib and object Source_stat.exp [prompt]> dir /b Source.cpp Source_stat.dll Source_stat.exp Source_stat.lib Source_stat.obj [prompt]> :: Build with dynamic libserial [prompt]> cl /nologo /I"%LIBSERIAL_DIR%\include" /EHsc /MD /DLIBSERIAL_DYNAMIC /c Source.cpp /FoSource_dyn.obj Source.cpp [prompt]> link /NOLOGO /DLL /LIBPATH:"%LIBSERIAL_DIR%\lib" Source_dyn.obj libserial.lib Creating library Source_dyn.lib and object Source_dyn.exp [prompt]> [prompt]> dir Volume in drive E is SSD0-WORK Volume Serial Number is AE9E-72AC Directory of e:\Work\Dev\Whosebug\q071859149 22/04/15 01:58 <DIR> . 22/04/15 01:58 <DIR> .. 22/04/15 01:50 394 Source.cpp 22/04/15 01:58 17,920 Source_dyn.dll 22/04/15 01:58 704 Source_dyn.exp 22/04/15 01:58 1,778 Source_dyn.lib 22/04/15 01:57 47,856 Source_dyn.obj 22/04/15 01:55 41,472 Source_stat.dll 22/04/15 01:55 707 Source_stat.exp 22/04/15 01:55 1,790 Source_stat.lib 22/04/15 01:55 46,299 Source_stat.obj 9 File(s) 158,920 bytes 2 Dir(s) 24,132,493,312 bytes free
2 个生成的 .dll 之间的“图形”比较。请注意,与 libserial.lib 链接的变体需要 libserial.dll: