如何在 C++ 中使用非托管 DLL win32应用程序?
我有一个第 3 方 DLL,我试图在 win32 C++ 应用程序中使用它。我所拥有的只有 DLL。我相信这个库是用 C 编写的,并且我假设它没有暴露给 COM。 LoadLibrary()是Windows中执行此任务必须常用的函数吗?如果是的话,有人可以给我提供一个如何使用它的例子吗?
我在 VS 中创建了一个空白的 win32,所以我没有包含任何特定于 Windows 的标头等。
谢谢!
更新
我想补充一点,我正在尝试使用似乎被广泛使用的 SDL 库。如果需要更多 DLL,供应商不会提供更多的内容,这似乎很奇怪。 简单的 DirectMedia 层
I have a 3rd party DLL that I am trying to use in a win32 C++ application. The DLL alone is all that I have. I believe this library is written in C and I assume is not exposed to COM. Is LoadLibrary() the function must commonly used for this task in Windows? If so can someone provide me with an example of how it is used?
I created a blank win32 in VS so I don't have any of the windows specific headers included etc.
Thanks!
UPDATE
I want to add that I am trying use the SDL Library which appears to be very widely used. It seems odd that the vendor would not provide more than the DLL if more is necessary.
Simple DirectMedia Layer
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,您可以使用
LoadLibrary
(实际上,如果您只有一个DLL,这是唯一的方法),但这还不够。要使用 DLL,您必须了解公开的函数声明(返回类型以及参数列表)。相反,您将无法使用 DLL。Yes, you can use
LoadLibrary
(actually if you only have a DLL, that is the only way) but it is not enough. To use a DLL you have to know exposed functions declarations (returned types as well as lists of arguments). In counterpart you'll not be able to use DLL.假设您确实有权访问头文件或具有标识函数及其参数的文档 - 这是它的样子
假设函数如下
int Func1 (int i1, int i2);
无效 Func2(无效);
现在下面是示例代码
如果您无权访问头文件或不知道函数签名 - 可能没有什么方法可以继续
- 运行一个使用此函数的程序,并在调用此函数时使用调试器中断并查看它的作用。
- 使用交互式反汇编程序(例如IDA Pro),它可以显示签名元素,例如向函数传递了多少参数。
- 反汇编函数以分析其序言和尾声。耗时且不是一项微不足道的任务,更重要的是因为不同的编译器、不同的调用约定、优化的代码加壳器等等。
- 我听人们说他们使用过 winedump - 你可以在这里查看 http://www. winehq.org/docs/winedump - 但我从未使用过它。 Nirsoft.net 的 DLL Export Viewer 或许是另一个工具。
- 这也是另一个工具 - Visual dumpbin 使用 UnDecorateSymbolName,该工具可在 http://code.entersources.com/f/Visual-Dumpbin-AC--Visual-GUI-for-Dumpbin_2_1671_0.aspx。 DLL 必须由 MS 编译器构建。检查此链接可能会给您更多线索,...
Assuming that you do have access to a header file or have documentation that identifies the function and their parameters - here is what it looks like
Assume that the functions are as follows
int Func1 (int i1, int i2);
void Func2(void);
Now what follows is the example code
If you do not have access to the header file or know the functions signature - there are perhaps few ways to proceed
- Run a program which uses this function and break with a debugger when this function is called and see what it does.
- Use interactive disassembler (for example, IDA Pro), it can show the signature elements such as how many parameters are passed into a function.
- Disassembling the function to analyze its prologue and epilogue. Time consuming and not a trivial task, more so because of the different compilers, different calling conventions, optimized code packers, and so on.
- I have heard people say that they have used winedump - you can check it out here http://www.winehq.org/docs/winedump - I have never used it though. Nirsoft.net's DLL Export Viewer is perhaps another tool.
- Also this is another tool- Visual dumpbin that uses UnDecorateSymbolName, the tool is available at http://code.entersources.com/f/Visual-Dumpbin-A-C--Visual-GUI-for-Dumpbin_2_1671_0.aspx. The DLL must be built by MS compiler. Check this link might give you some more clues, ...
您需要为您的应用程序手动创建一个导入库,以链接到 和 头文件以供您包含。希望它不是 C++。以下是有关如何开始的基本说明:如何在没有 .OBJ 或源的情况下创建 32 位导入库
You need to manually create an import library for your application to link against and and header files for you to include. Hopefully it's not C++. Here are basic instructions on how to get started: How To Create 32-bit Import Libraries Without .OBJs or Source
也许这里最好的做法是定义一个类来为您调用
LoadLibrary
,这样您就不会忘记稍后调用FreeLibrary
。例如,请参阅 https://bitbucket.org/BillyONeal/pevfind/src /ed3a0f5c37c4/pevFind/Win32RuntimeDynamicLinker.hpp请注意,您确实可以在此处删除 boost 内容 - 它只是为了确保在有人尝试使用 WindowsApi::RuntimeDynamicLinker 时在编译时抛出错误消息: :GetFunction其中
t
不是某种形式的函数指针。Probably the best thing to do here is to define a class to do the calling of
LoadLibrary
for you, so that you can't forget to callFreeLibrary
later. For example, see https://bitbucket.org/BillyONeal/pevfind/src/ed3a0f5c37c4/pevFind/Win32RuntimeDynamicLinker.hppNote that you really could strip out the boost stuff here -- it's only there to ensure error messages get thrown at compile time if someone tries to use
WindowsApi::RuntimeDynamicLinker::GetFunction<t>
wheret
is not some form of function pointer.您需要的不仅仅是 DLL。至少您需要了解函数、它们的参数以及它们的语义。如果没有它,您将无法实际使用该 DLL。最好的起点是询问 DLL 供应商。
但如果您遇到困难,那么这里有一些您可以开始的方法...
使用 dumpbin.exe 获取有关 DLL 的一些信息。或者,您可以使用depends.exe 进行图形视图。这两个程序都位于 Visual Studio 文件夹中的某个位置。
dumpbin.exe /exports 将显示导出的函数。这些是您可以从应用程序调用的函数。每个函数都有一个名称和一个序数,您可以稍后在 GetProcAddress 中使用其中任何一个。
如果您看到名为 DllCanUnloadNow、DllRegisterServer 等的函数,那么它就是一个 COM DLL。在这种情况下,您将需要相应的类型库。如果您询问,DLL 供应商可能会向您发送类型库。某些 DLL 将其类型库存储为资源 - 您可以直接在 Visual Studio 中打开 DLL 并查找“TYPELIB”类型的资源。如果有类型库资源,那么您可以将其导出并将其另存为whatever.tlb,然后在 OleViewer 或 Visual Studio 的类型查看器中打开它 - 无论哪种方式,您都可以开始使用。
如果它不是 COM DLL,那么您可以使用 LoadLibrary 加载它,然后使用 GetProcAddress 获取指向该函数的指针。但是,要使用该函数,您必须将返回的 FARPROC 指针转换为指向适当类型的函数的指针 - 如果您是新手,那么这并不简单。
如果 DLL 中的函数名称被破坏,例如 ?whatever@@YAHXZ ,那么它是一个 C++ 函数,您必须使用用于构建 DLL 的相同编译器。 (不一定,但总的来说。)但是用 C++ 编写的 DLL 通常会通过 C 链接导出函数,所以幸运的话您不必担心这一点。
dumpbin.exe /dependents 将显示您的 DLL 使用的其他 DLL 的列表。如果您看到 mscoree.dll,那么它使用 .NET。在这种情况下,您必须在用户的计算机上安装适当的 .NET 运行时。
You'll need more than just the DLL. At the least you'll need to know the functions, their parameters, and their semantics. Without that, you won't be able to make practical use of the DLL. Best place to start is to ask the DLL vendor.
But if you're stuck, then here are some ways you might get started...
Use dumpbin.exe to get some info about the DLL. Alternatively you can use depends.exe for a graphical view. Both of these programs will be somewhere in you Visual Studio folder.
dumpbin.exe /exports will show you the exported functions. These are the functions you can call from your application. Each function has a name and an ordinal, and you can use either of these later in GetProcAddress.
If you see functions called DllCanUnloadNow, DllRegisterServer, etc. then it's a COM DLL. In that case you'll need the corresponding type library. The DLL vendor will probably send you the type library if you ask them. Some DLLs store their type libraries as resources - you can open the DLL directly in Visual Studio and look for a resource of type "TYPELIB". If there is a typelibrary resource then you can export it and save it as whatever.tlb, and then open it in OleViewer or Visual Studio's type viewer - either way, you're ready to start playing around.
If it's not a COM DLL then you can use LoadLibrary to load it, and then GetProcAddress to get a pointer to the function. However, to use the function you'll have to cast the returned FARPROC pointer to a pointer to a function of the appropriate type - that's not straightforward if you're new to this kind of thing.
If a function name in the DLL is mangled, something like ?whatever@@YAHXZ then it's a C++ function and you'll have to use the same compiler that was used to build the DLL. (Not necessarily, but by and large.) But DLLs written in C++ often export functions with C linkage, so with luck you won't have to worry about this.
dumpbin.exe /dependents will show you the list of other DLLs that your DLL uses. If you see mscoree.dll then it uses .NET. In that case you'll have to have the appropriate .NET runtime installed on your user's computer.