C++ 从C+调用Win32 DLL+;

C++ 从C+调用Win32 DLL+;,c++,winapi,dll,C++,Winapi,Dll,我是新来的。我得到了一个有很多函数的Win32 DLL。需要从C++ 调用这些DLL函数 < P>我想调用 CreateNewScanner < /Cord>,它创建一个新的扫描器对象并以C++获得结果。 DLL中提到的函数是: BOOL CreateNewScanner(NewScanner *newScan); 而NewScanner是一个struct,如下所示 // Structure NewScanner is defined in "common.h" . typedef struc

我是新来的。我得到了一个有很多函数的Win32 DLL。需要从C++

调用这些DLL函数 < P>我想调用<代码> CreateNewScanner < /Cord>,它创建一个新的扫描器对象并以C++获得结果。 DLL中提到的函数是:

BOOL CreateNewScanner(NewScanner *newScan);
NewScanner
是一个
struct
,如下所示

// Structure NewScanner is defined in "common.h" .
typedef struct{
  BYTE host_no; // <- host_no =0
  LONG time; // <- command timeout (in seconds)
  BYTE status; // -> Host adapter status
  HANDLE obj; // -> Object handle for the scanner
}NewScanner;
//结构NewScanner在“common.h”中定义。
类型定义结构{
BYTE host_no;//扫描仪的对象句柄
}新闻播音员;
我将如何调用此函数?从C++开始,这里是我管理的,

#include <iostream>
#include <windows.h>
using namespace std;
int main(){
  HINSTANCE hInstance;    
  if(!(hInstance=LoadLibrary("WinScanner.dll"))){
      cout << "could not load library" << endl;        
  }
  /* get pointer to the function in the dll*/
  FARPROC handle = GetProcAddress(HMODULE(hInstance), "CreateNewScanner");
  if(!handle){
    // Handle the error
    FreeLibrary(hInstance);
    return "-1";
  }else{    
    // Call the function
    //How to call here??
  }
}
#包括
#包括
使用名称空间std;
int main(){
HINSTANCE HINSTANCE;
如果(!(hInstance=LoadLibrary(“WinScanner.dll”)){

cout首先,
return“-1”
不好。你应该返回一个整数。所以你的意思肯定是
return-1

现在进入问题。与其将函数指针声明为
FARPROC
,不如将其声明为函数指针类型

typedef BOOL (*CreateNewScannerProc)(NewScanner*);
然后按如下方式调用GetProcAddress:

HMODULE hlib = LoadLibrary(...);
// LoadLibrary returns HMODULE and not HINSTANCE
// check hlib for NULL

CreateNewScannerProc CreateNewScanner = 
    (CreateNewScannerProc) GetProcAddress(hlib, "CreateNewScanner");
if (CreateNewScanner == NULL)
    // handle error

// now we can call the function
NewScanner newScan;
BOOL retval = CreateNewScanner(&newScan);
综上所述,通常一个库会附带一个头文件(您的头文件显然是这样的,您应该包含它)和一个用于加载时链接的.lib文件。请确保将.lib文件传递给链接器,您只需执行以下操作:

#include "NameOfTheHeaderFileGoesHere.h"
....
NewScanner newScan;
BOOL retval = CreateNewScanner(&newScan);

<>不必乱搞<代码> LoadLibrary <代码> >代码> GePosiLoad < /代码>等。

< p>如果您想遵循<代码> LoadLibrary <代码> >代码> GETPROCELATION>代码> >代码> FreeLibrary < /Cord>方法,请考虑下面的“代码路径”(注意,如果你有DLL公共头文件和相应的.LIB文件,只要<代码>包含了.DLL头,并链接到.LIB文件,只使用它的原型在DLL头中定义的函数,就像用C++代码调用的普通C函数一样。” 为指向从DLL导出的函数的指针定义
typedef

请注意,指定了调用约定(通常,带有纯C接口的Win32 DLL使用):

然后尝试使用加载库加载DLL:

//
// Try loading the DLL.
//
HMODULE hDll = LoadLibrary(L"WinScanner.dll"); // <--- Note the use of L"..." for Unicode
if (! hDll)
{
    .... error
}
//
// Try getting the pointer to CreateNewScanner DLL function.
//
auto pCreateNewScanner = reinterpret_cast<CreateNewScannerPtr>
(
  GetProcAddress
  (
    hDll,               // DLL handle
    "CreateNewScanner"  // Function name
  ) 
);

if (! pCreateNewScanner)
{
    .... error

    // Release the DLL
    FreeLibrary(hDll);

    // Avoid dangling references
    hDll = nullptr;
}
//
// Release the DLL
//
FreeLibrary(hDll);
hDll = nullptr;

注意,由于使用C++,最好使用C++风格的转换(如<代码> RealTytCase<代码>),而不是旧的C样式转换。 此外,由于函数指针的类型是在

reinterpret\u cast
中指定的,因此在语句开头重复它是没有用的,因此可以使用新的C++11关键字
auto

可以使用返回的函数指针调用DLL函数:

BOOL retCode = pCreateNewScanner( .... );

// Note: some other common prefix used in this case is "pfn"
// as "pointer to function" (e.g. pfnCreateNewScanner).
使用完DLL后,可以调用FreeLibrary释放它:

//
// Try loading the DLL.
//
HMODULE hDll = LoadLibrary(L"WinScanner.dll"); // <--- Note the use of L"..." for Unicode
if (! hDll)
{
    .... error
}
//
// Try getting the pointer to CreateNewScanner DLL function.
//
auto pCreateNewScanner = reinterpret_cast<CreateNewScannerPtr>
(
  GetProcAddress
  (
    hDll,               // DLL handle
    "CreateNewScanner"  // Function name
  ) 
);

if (! pCreateNewScanner)
{
    .... error

    // Release the DLL
    FreeLibrary(hDll);

    // Avoid dangling references
    hDll = nullptr;
}
//
// Release the DLL
//
FreeLibrary(hDll);
hDll = nullptr;

此外,请注意,您可以使用,并定义一个具有自动释放DLL的析构函数的类(这简化了管理库加载/释放部件的代码)。
e、 g

然后,在某些代码块中,您可以:

{
    // Load the library (throws on error).
    RaiiDll scannerDll(L"WinScanner.dll");

    // Get DLL function pointer
    auto pCreateNewScanner = reinterpret_cast<CreateNewScannerPtr>( 
        GetProcAddress(scannerDll.Get(), "CreateNewScanner"));
    if (! pCreateNewScanner)
    {
        .... error.       
    }

    .... use the function

} // <--- DLL automatically released thanks to RaiiDll destructor!!!
{
//加载库(出错时抛出)。
RaiiDll scannerDll(L“WinScanner.dll”);
//获取DLL函数指针
自动pCreateNewScanner=重新解释广播(
GetProcAddress(scannerDll.Get(),“CreateNewScanner”);
如果(!pCreateNewScanner)
{
……错误。
}
…使用该功能

} //Note,我使用C样式的转换,因为我不确定AcKER对于C++风格的转换是非常好的。我已经编辑了这个问题,只是添加了更好的文本格式。