如何在C ++ win32应用程序中使用非托管DLL?

时间:2010-12-26 01:39:26

标签: c++ visual-studio-2008

我有一个第三方DLL,我试图在win32 C ++应用程序中使用。仅DLL就是我所拥有的。我相信这个库是用C语言编写的,我认为不会暴露给COM。 LoadLibrary()函数必须在Windows中常用于此任务吗?如果是这样,有人能为我提供一个如何使用它的例子吗?

我在VS中创建了一个空白的win32,因此我没有包含任何特定于Windows的标题等。

谢谢!

更新

我想补充一点,我正在尝试使用看似广泛使用的SDL库。如果需要更多,供应商不会提供更多的DLL似乎很奇怪。 Simple DirectMedia Layer

5 个答案:

答案 0 :(得分:2)

是的,您可以使用LoadLibrary(实际上,如果您只有DLL,这是唯一的方法),但这还不够。要使用DLL,您必须知道公开的函数声明(返回的类型以及参数列表)。在对应物中,您将无法使用DLL。

答案 1 :(得分:0)

您需要手动为应用程序创建一个导入库,以链接和要包含的头文件。希望它不是C ++。以下是有关如何入门的基本说明:How To Create 32-bit Import Libraries Without .OBJs or Source

答案 2 :(得分:0)

这里最好的办法是定义一个类来为你调用LoadLibrary,这样你就不会忘记稍后再调用FreeLibrary。例如,请参阅https://bitbucket.org/BillyONeal/pevfind/src/ed3a0f5c37c4/pevFind/Win32RuntimeDynamicLinker.hpp

请注意,你真的可以删除这里的提升内容 - 只有在那里确保错误消息在编译时被抛出,如果有人试图使用WindowsApi::RuntimeDynamicLinker::GetFunction<t> t不是某种形式的函数指针。

答案 3 :(得分:0)

您需要的不仅仅是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中的函数名称被破坏,那么类似于@@ YAHXZ,那么它就是一个C ++函数,你将不得不使用用于构建DLL的相同编译器。 (不一定,但总的来说。)但是用C ++编写的DLL经常使用C链接导出函数,所以运气好的话就不用担心了。

dumpbin.exe / dependents将显示您的DLL使用的其他DLL的列表。如果你看到mscoree.dll,那么它使用.NET。在这种情况下,您必须在用户的计算机上安装适当的.NET运行时。

答案 4 :(得分:0)

假设您确实可以访问头文件或拥有标识功能及其参数的文档 - 这就是它的样子

假设功能如下
int Func1(int i1,int i2);
void Func2(void);

以下是示例代码

#include windows.h  
#include stdio.h  
// use either dumpbin or http://www.dependencywalker.com/ to confirm the functions  
//Let us assume it has two functions with their prototypes known - Func1 & Func2  
int Func1 (int i1, int i2);  
void Func2(void);  
typedef int (*FUNC1_PTR) (int, int);  
typedef void (*FUNC2_PTR) (void);  
const char NONAME_DLL[] = "some.dll";  
int main(int argc, char *argv[]) {  
    FUNC1_PTR f1;  
    //FUNC2_PTR F2;  
    int i= 1, j = 2;  
    HMODULE hMod = LoadLibrary(NONAME_DLL);  
    if (!hMod) {  
        printf("LoadLibrary fails with error code %d \n", GetLastError());  
        return 1;  
    }  
    f1 = (FUNC1_PTR) GetProcAddress(hMod, "Func1");  
    if (f1) {  
        int ret = (*f1)(i, j);  
    }  
    FreeLibrary (hMod);  
    return 0;  
}  

如果您无权访问头文件或了解功能签名 - 可能没有多少方法可以继续进行 - 运行一个程序,该程序使用此函数,并在调用此函数时与调试器断开并查看它的作用   - 使用交互式反汇编程序(例如,IDA Pro),它可以显示签名元素,例如将多少参数传递到函数中。
- 拆解功能以分析其序言和结语。由于不同的编译器,不同的调用约定,优化的代码打包器等,所以耗费时间而不是一项微不足道的任务。 - 我听说有人说他们使用过winedump - 你可以在这里查看http://www.winehq.org/docs/winedump - 我从来没用过它。 Nirsoft.net的DLL导出查看器可能是另一种工具 - 这也是另一个工具 - 使用UnDecorateSymbolName的Visual dumpbin,该工具在http://code.entersources.com/f/Visual-Dumpbin-A-C--Visual-GUI-for-Dumpbin_2_1671_0.aspx可用。 DLL必须由MS编译器构建。查看此链接可能会为您提供更多线索,......