繁体   English   中英

从C#调用C ++ dll方法/类

[英]Call C++ dll methods/classes from C#

我写了一些软件来自动化一些第三方软件,并发现有必要研究调用该软件自己的dll。


注意 :很遗憾,我无权访问源或开发人员


使用PInvoke调用dll的静态方法非常容易,但是据我所知,没有C ++ / CLI包装器,实例化类是不可能的。

答案似乎是围绕dll创建一个C ++ / CLR包装器,如本答案所示 虽然显然是一个出色答卷,我从来没有之前创建一个C ++应用程序,不知道该怎么

我已经使用过依赖遍历程序来获取我想使用的函数名: sdk_string::sdk_string(const char *) (修饰为: ??0sdk_string@@QAE@XZ )。 在那个入口点尝试PInvoke只会以悲伤和自怜告终。

从我收集的资料中,我需要:

  1. 创建一个新的Visual C ++ CLR类库。
  2. 在主.h头文件中,编写如下内容: sdk_string* CreateSdkString(const char * chars) { return new sdk_string(chars); } sdk_string* CreateSdkString(const char * chars) { return new sdk_string(chars); }
  3. 以某种方式获得new sdk_string(chars)调用以调用第三方dll?
  4. ?????? (是否需要以任何特殊方式构建它,以便可以轻松地CreateSdkString调用我的CreateSdkString函数?)
  5. 支持并接受您的答案。 :-)

我认为上面的步骤3是我的问题: 如何获得new sdk_string(chars)调用以调用第三方dll? 但是,如果我在其他事情上错了,那么其他我错的问题就是我的问题。

更新:

仅供参考,以下是该类的整个Dependency Walker函数名称输出:

const sdk_string ::`vftable'
sdk_string和sdk_string :: append类(sdk_string const&类)
sdk_string和sdk_string :: append(char)类
sdk_string和sdk_string :: append(char *)类
类sdk_string和sdk_string :: append(char const *)
char const * sdk_string :: c_str(void)
bool sdk_string :: contains(char const *)
布尔sdk_string :: empty(void)
布尔sdk_string :: endsWith(char const *)
int sdk_string :: equals(class sdk_string const&)
int sdk_string :: equals(char const *)
int sdk_string :: equalsIgnoreCase(class sdk_string const&)
int sdk_string :: equalsIgnoreCase(char const *)
无效sdk_string :: erase(int,int)
布尔sdk_string :: hasAlphaChars(void)
int sdk_string :: indexOf(class sdk_string const&)
int sdk_string :: indexOf(char)
int sdk_string :: indexOf(char,int)
int sdk_string :: indexOf(char const *)
无效sdk_string :: insert(int,char const *)
布尔sdk_string :: isAllDigits(void)
布尔sdk_string :: isAllWhiteSpace(void)
int sdk_string :: length(void)
类sdk_string和sdk_string :: operator =(类sdk_string const&)
sdk_string和sdk_string :: operator =(char *)类
无效sdk_string :: replace(int,int,class sdk_string const&)
无效sdk_string :: replace(char const *)
sdk_string :: sdk_string(wchar_t *&)
sdk_string :: sdk_string(sdk_string const&类)
sdk_string :: sdk_string(char const *)
sdk_string :: sdk_string(无效)
无效sdk_string :: setData(char const *)
布尔sdk_string :: startsWith(char const *)
布尔sdk_string :: stretch(int)
无效sdk_string :: stripLeadingSpaces(void)
无效sdk_string :: stripSpaces(void)
无效sdk_string :: stripTrailingSpaces(void)
无效sdk_string :: substr(int,int,class sdk_string&)
无效sdk_string :: toUpper(class sdk_string&)
sdk_string ::〜sdk_string(无效)

我想我缺少一些真正显而易见的难题……如何将第三方.dll中的函数/类放入新的C ++ / CLR包装器中,以便我可以调用它

您可以使用头文件并导入非托管库随附的库,就像将任何DLL导入非托管项目一样。 将头文件包含在引用该库的任何源文件中,然后将导入库传递给链接器。

但是,在DLL中实现的已发布的基于C ++类的接口令人惊讶。 在选择编译器方面,这给您带来了严格的限制。 我怀疑您是对私有库进行反向工程,因此没有头文件或导入库。 对它们进行逆向工程可能是一个无法追踪的问题。 我建议与图书馆的开发人员联系以获得支持。

显然,您只需要一些方法/功能,因此在这种情况下,您能做的最好的事情就是创建头文件(您的选项2)。 如果需要更多(很多)类/方法,可以查看http://www.swig.org/,它可以创建C#的包装,但是需要定义,例如,您可以创建头文件,让其命名它是myHeader.h,如下所示:

class A
{
public:
int intMethod(float param);
}

创建文件后,请使用以下内容将其命名为myHeader.i:

%module myHeader_wrapper
%{
//Here could be the header file or directly the class/functions definition
    #include "myHeader.h"
%}
%include "myHeader.h"

之后,您运行:

swig -csharp myHeader.i

应该创建一个名为myHeader_wrap.c和myHeader.cs的文件。 使用.c文件创建C ++ dll,并使用C#项目中的.cs文件访问类。 当然,可以使用您的IDE工具自动完成这件事(例如,使Visual Studio运行后生成操作)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM