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

问题描述 投票:-1回答:2

我编写了一些软件来自动化一些第三方软件,并发现有必要调查那个软件自己的dll。


注意:不幸的是,我无权访问源代码或开发人员


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

答案似乎是围绕dll创建一个C ++ / CLR包装器,如this answer所示。虽然显然是一个很好的答案,但我以前从未创建过C ++应用程序,也不知道该做什么。

我已经使用了依赖walker来获取我想要使用的函数名: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); }
  3. 以某种方式得到new sdk_string(chars)呼叫呼叫进入第三方DLL?
  4. ?????? (我需要以任何特殊方式构建它,以便我可以轻松地使用我的CreateSdkString函数吗?)
  5. Upvote并接受你的回答。 :-)

我认为上面的第3步是我的问题:如何让new sdk_string(chars)呼叫进入第三方dll?但如果我对其他事情的看法不对,那么我错的其他事情就是我的问题。

更新:

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

const sdk_string ::`vftable' class sdk_string&sdk_string :: append(class sdk_string const&) class sdk_string&sdk_string :: append(char) class sdk_string&sdk_string :: append(char *) class sdk_string&sdk_string :: append(char const *) char const * sdk_string :: c_str(void) bool sdk_string :: contains(char const *) bool sdk_string :: empty(void) bool 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 *) void sdk_string :: erase(int,int) bool 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 *) void sdk_string :: insert(int,char const *) bool sdk_string :: isAllDigits(void) bool sdk_string :: isAllWhiteSpace(void) int sdk_string :: length(void) class sdk_string&sdk_string :: operator =(class sdk_string const&) class sdk_string&sdk_string :: operator =(char *) void sdk_string :: replace(int,int,class sdk_string const&) void sdk_string :: replace(char const *) sdk_string :: sdk_string(wchar_t *&) sdk_string :: sdk_string(class sdk_string const&) sdk_string :: sdk_string(char const *) sdk_string :: sdk_string(无效) void sdk_string :: setData(char const *) bool sdk_string :: startsWith(char const *) bool sdk_string :: stretch(int) void sdk_string :: stripLeadingSpaces(void) void sdk_string :: stripSpaces(void) void sdk_string :: stripTrailingSpaces(void) void sdk_string :: substr(int,int,class sdk_string&) void sdk_string :: toUpper(class sdk_string&) sdk_string ::〜sdk_string(无效)

c# visual-c++ dll pinvoke
2个回答
1
投票

我想我错过了一些非常明显的难题......如何从第三方.dll中获取函数/类到我的新C ++ / CLR包装器中,以便我可以调用它

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

但是,在DLL中实现的已发布的基于C ++类的接口令人惊讶。它对编译器的选择有严格的限制。我怀疑你是对一个私有库进行逆向工程,因此不会有头文件或导入库。对它们进行逆向工程可能是一个难以追究的问题。我建议联系图书馆的开发者寻求支持。


0
投票

显然你只需要一些方法/功能,所以在这种情况下你可以做的最好的是创建头文件(你的选项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工具自动化swig事物(例如,使visual studio运行后构建操作)。

© www.soinside.com 2019 - 2024. All rights reserved.