如何引用没有类/命名空间的C ++库?

时间:2014-01-10 21:18:30

标签: visual-c++

我有一个第三方C ++ .lib,我想在C#应用程序中使用。

我的目的是为.lib编写托管C ++包装器.dll,然后在我的C#应用​​程序中包含该包装器dll,使用大致类似the one outlined at this link的过程。

.lib的头文件不表示任何类声明或命名空间,只是方法名称:

int CheckNamedVariable(const char* _name);
int RegisterNamedVariable(const char* _name);
double GetNamedVariableValue(int _id);
double GetNamedVariableTypedValue(int _id, int _units);
void SetNamedVariableValue(int _id, double _value);
... (etc)

我用DUMPBIN / exports检查了lib,看看是否可以收集任何其他信息,并得到以下信息:

File Type: LIBRARY

     Exports

       ordinal    name

                  ?AircraftVarGet@@YANHHH@Z (double __cdecl AircraftVarGet(int,int,int))
                  ?CheckNamedVariable@@YAHPBD@Z (int __cdecl CheckNamedVariable(char const *))
                  ?DLLStart@@YGXXZ (void __stdcall DLLStart(void))
                  ?DLLStop@@YGXXZ (void __stdcall DLLStop(void))
                  ?GetAircraftVarEnum@@YAHPBD@Z (int __cdecl GetAircraftVarEnum(char const *))
                  ?GetModuleVar@@YANW4GAUGE_TOKEN@@@Z (double __cdecl GetModuleVar(enum GAUGE_TOKEN))
                  ?GetNameOfNamedVariable@@YAPBDH@Z (char const * __cdecl GetNameOfNamedVariable(int))
                  ?GetNamedVariableTypedValue@@YANHH@Z (double __cdecl GetNamedVariableTypedValue(int,int))
                  ?GetNamedVariableValue@@YANH@Z (double __cdecl GetNamedVariableValue(int))
                  ?GetUnitsEnum@@YAHPBD@Z (int __cdecl GetUnitsEnum(char const *))
                  ?IsPanelWindowVisibleIdent@@YAHI@Z (int __cdecl IsPanelWindowVisibleIdent(unsigned int))
                  ?Panels@@3PAUPANELS@@A (struct PANELS * Panels)
                  ?RegisterNamedVariable@@YAHPBD@Z (int __cdecl RegisterNamedVariable(char const *))
                  ?SendKeyEvent@@YAXII@Z (void __cdecl SendKeyEvent(unsigned int,unsigned int))
                  ?SetNamedVariableTypedValue@@YAXHNH@Z (void __cdecl SetNamedVariableTypedValue(int,double,int))
                  ?SetNamedVariableValue@@YAXHN@Z (void __cdecl SetNamedVariableValue(int,double))
                  _ImportTable
                  _Linkage

  Summary

          ED .debug$S
          14 .idata$2
          14 .idata$3
           4 .idata$4
           4 .idata$5
          1A .idata$6

在我的托管包装器项目中,我可以将链接器输入指向.lib,但我不确定如何调用lib中的方法(我链接的教程使用了命名空间和类)。如果它是C#/ VB项目中的普通旧DLL,我可以查看对象浏览器并了解如何调用库。

但鉴于我的C ++无知,我处于黑暗中。任何帮助表示赞赏。

修改 我尝试创建与标题中列出的方法同名的方法,例如:

int VariableExporter::IsPanelWindowVisibleIdent(unsigned int panel_id)
{
    return IsPanelWindowVisibleIdent(panel_id); 
}

这不是我希望的,它只是递归地调用自己(直到它有 - 等待它 - Stack Overflow)。

然后我尝试重命名包装器方法,如下所示:

int VariableExporter::IsPanelWindowVisibleIdent_New_Name(unsigned int panel_id)
{
    return IsPanelWindowVisibleIdent(panel_id); 
}

现在,虽然C ++ .DLL项目和C#项目都是编译的,但C#项目在尝试加载.DLL时会抛出一个FileNotFound异常。

1 个答案:

答案 0 :(得分:1)

首先,要调用全局级别函数,您需要使用范围解析运算符::

int VariableExporter::IsPanelWindowVisibleIdent(unsigned int panel_id)
{
    return ::IsPanelWindowVisibleIdent(panel_id); 
}

没有必要(至少在这个简单的情况下)重命名你的方法。

其次,对于DLL-not-found问题,请检查C#应用程序的bin路径中是否存在DLL。另外,检查wrapper-DLL本身是否可加载(使用Dependency Walker)。确保包装器DLL和C#应用程序的位相匹配。 64位应用程序无法加载32位DLL(反之亦然)。