如何静态链接一个.DLL?

28
我们有一个使用纯本地C++编写、由VS构建的DLL。我们的客户端包括一些本地C++应用程序和一个使用C++/CLI编写的.NET包装器,最后还有一些使用C#编写的针对.NET包装器的客户端应用程序。
我的问题是原生.DLL必须以不同于.NET世界的方式分发,并且VS不会跟踪该DLL的使用情况。为了让所有C#应用程序正常工作,我必须将其复制到每个可执行目录中,或者将其放在%PATH%(我希望在开发人员计算机上避免这样做,因为他们可能希望使用不同版本的DLL启动不同的应用程序)。
如果有引用Wrapper-DLL的用户控件,将会出现更大的问题:您必须将DLL复制到VS的目录或者再次复制到%PATH%中。但是最糟糕的情况发生在我们的Translator工具上。该工具跟踪.NET程序集并将它们打包成可以发送给外部翻译器的Translator包。据我所知,没有办法将本地.DLL放入该包中!
因此,我计划将本地DLL静态链接到.NET-Wrapper中,这将解决我的问题。但对于我们的本地应用程序,这个本地DLL仍然必须是一个DLL。
所以我有两个选择:
- 创建两个项目(一个生成静态库,另一个创建动态库=>我试图避免这种情况) - 找到将DLL静态链接的解决方案 - 找到让VS从一个项目生成两个输出的方法

我可能有点傻,但我不明白为什么你的本地应用程序不能使用本地dll,而你的.net应用程序使用c++/cli包装的dll。 - Niklas
它们都可以。但是Wrapper-DLL引用了本地DLL,因此我的C#应用程序需要两者。这对于包装器来说还好,但对于本地DLL来说很麻烦。 - mmmmmmmm
为什么不为dll构建一个库呢?你说你是用VS构建的dll,对吧? - Henry B
在Visual Studio 2019中如何完成这个操作? - user15638203
4个回答

7
在C++项目文件中创建两个配置项,一个生成DLL,一个生成.lib。不需要两个项目,因为任何.NET/C++项目都可以支持多个构建配置(这就是发布版本和调试版本的构建方式不同的原因)。

1
但是有没有办法一次构建同一项目的两个配置呢?通常情况下,您可以在配置管理器中为解决方案配置/平台选择一个项目配置/平台。 - mmmmmmmm
1
你可以复制这个项目,并在该解决方案中配置一个不同的副本。别忘了设置不同的中间目录。 - thewhiteambit

6

另一个选项是创建两个项目,一个项目将输出一个可以静态链接的 .lib 文件,而第二个项目将输出一个 .dll 文件,并以您的 .lib 作为依赖项。您应该在您的 .dll 中添加 .def 来导出您计划导出的符号,否则它将为空。


好的,我会试一下。目前我通过将obj文件作为额外输入添加到包装DLL(../NativeLib/$(PlatformName)/$(ConfigurationName)/*.obj)中来解决问题。但这有点粗糙,你的选项听起来更好! - mmmmmmmm
有人能解释一下在这种情况下如何区分.lib和.dll吗? - Iqra.
在Visual Studio中,您有两种不同的应用程序类型:“静态库”和“DLL”。 “静态库”选项会创建一个“.lib”文件,但它不能直接执行,对象代码被全部放在一起而没有进行处理。 “DLL”选项将创建一个可执行的“.dll”文件(即您可以通过LoadLibrary使用它),对象代码被处理以解决函数调用并进行优化。 - Ismael

5

如果你找不到更便宜的选择,就拿一份DLL to Lib的副本。


8
有点贵,不是吗? - mmmmmmmm
2
考虑到您已经拥有 DLL 的源代码,这尤其昂贵。您可以将其简单地重新编译为静态库文件。但 .Net 不会使用它,因为 .Net 不支持库文件。这也意味着 DLL To Lib 不能帮助您。 - Rob Kennedy
1
是的,我刚刚检查了一下,我正在运行1.42版本,这个版本在2003年售价为99美元,当时是一个可以接受的价格。 - SmacL
2
如果您有DLL的源代码,请构建一个LIB并使用它来进行静态链接?或者您没有DLL的源代码? - Henry B
1
如果DLL To Lib能够正常工作,那么你就不需要它。VS已经完全能够从你的代码中创建一个lib文件了。如果你可以将一个.lib文件链接到你的.Net项目中,那就这样做吧。不过,我的印象是.Net程序集不能与本地的.lib文件进行链接。 - Rob Kennedy
显示剩余5条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接