我编写了一些软件来自动化某些第三方软件,并发现有必要调查该软件自己的dll。
注意:不幸的是,我不有权访问源代码或开发人员
使用PInvoke很容易调用dll的静态方法,但据我所知,没有C ++ / CLI包装器就无法实例化类。
答案似乎是围绕dll创建一个C ++ / CLR包装器,如this answer中所示。 虽然显然是一个很好的答案,但我以前从未创建过C ++应用程序,也不知道完全该做什么。
我已经使用了依赖walker来获取我想要使用的函数名:sdk_string::sdk_string(const char *)
(如装饰:??0sdk_string@@QAE@XZ
)。在那个入口点尝试PInvoke只会以悲伤和自怜结束。
从我收集的内容来看,我需要:
sdk_string* CreateSdkString(const char * chars) { return new sdk_string(chars); }
new sdk_string(chars)
来调用第三方dll?CreateSdkString
功能?)我认为上面的第3步是我的问题:如何调用new sdk_string(chars)
来调用第3方dll?但如果我对其他事情不对,那么那些其他我错的是我的问题。
更新
仅供参考,以下是此类的整个Dependency Walker函数名称输出:
const sdk_string ::`vftable'
class sdk_string& sdk_string :: append(class sdk_string const&)
class sdk_string& sdk_string ::追加(焦炭)
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(void)
答案 0 :(得分:1)
我想我错过了一些非常明显的难题......如何从第三方.dll中获取函数/类到我的新C ++ / CLR包装中,以便我可以调用它
使用非托管库提供的头文件和导入库,就像将任何DLL导入非托管项目一样。在任何引用库的源文件中包含头文件,并将导入库传递给链接器。
但是,在DLL中实现的已发布的基于C ++类的接口令人惊讶。它对编译器的选择有严格的限制。我怀疑你是对一个私有库进行逆向工程,因此不会有头文件或导入库。对它们进行逆向工程可能是一个难以追究的问题。我建议联系图书馆的开发者寻求支持。
答案 1 :(得分: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运行后构建操作)。