C#调用C++类的疑问
假设现有一C++类库a.dll,里面有个classb,请问各位高手如何才能在C#中调用这个classb并且实例化?a.dll由C++编译出来的,不能在C#中直接引用啊...
假设现有一C++类库a.dll,里面有个class b,请问各位高手如何才能在C#中调用这个class b并且实例化?
a.dll由C++编译出来的,不能在C#中直接引用啊 展开
a.dll由C++编译出来的,不能在C#中直接引用啊 展开
6个回答
展开全部
基本上回答是调不了,原因来自引用名和调用约定两方面。这个需要从VC++导出类的原理说起。
类从本质上来说是数据结构和封装的操作两部分。数据结构定义在头文件当中,编译的时候就可以访问到;而成员函数是从DLL中导出的。导出C++类库的时候,这些函数名字会按照编译器的标准做一个扩展,比如说
class B{
int Operator(int a, int b);
};
里面的Operator这个成员函数,实际上会被编译成类似于这样的一个函数:
int __thiscall B_Operatorxxxxxx(B* _this, int a, int b);
(__thiscall这个关键字其实是C++里没有的)
注意到名字后面增加了一些像乱码一样的东西,这是C++编译器根据后面的参数列表自动生成的一个后缀。因为这个后缀的存在,相同名字不同参数的函数和成员函数才可以一起存在在代码里(即所谓的重载)。
这也就是说,想要调用C++类库里的函数的话,至少要知道编译器把这个函数编译成了什么名字,但实际上不同的编译器编译出来的结果都不一样。
其实这也算不上什么问题,编译的时候如果设置输出详细信息的话是有办法能查到实际编译成什么名字了的。更严重的问题来自调用约定:
正如上文中提到的,C++的成员函数采用__thiscall的调用约定。所谓调用约定,是指在调用函数时如何传递参数,用什么顺序传递参数,以及由谁来负责清理堆栈的约定。__thiscall这个调用约定是不被托管程序的[DllImport]属性支持的。
当然不排除一些拐弯抹角的方法是能调用的。即便如此也是极其不推荐的做法。
类从本质上来说是数据结构和封装的操作两部分。数据结构定义在头文件当中,编译的时候就可以访问到;而成员函数是从DLL中导出的。导出C++类库的时候,这些函数名字会按照编译器的标准做一个扩展,比如说
class B{
int Operator(int a, int b);
};
里面的Operator这个成员函数,实际上会被编译成类似于这样的一个函数:
int __thiscall B_Operatorxxxxxx(B* _this, int a, int b);
(__thiscall这个关键字其实是C++里没有的)
注意到名字后面增加了一些像乱码一样的东西,这是C++编译器根据后面的参数列表自动生成的一个后缀。因为这个后缀的存在,相同名字不同参数的函数和成员函数才可以一起存在在代码里(即所谓的重载)。
这也就是说,想要调用C++类库里的函数的话,至少要知道编译器把这个函数编译成了什么名字,但实际上不同的编译器编译出来的结果都不一样。
其实这也算不上什么问题,编译的时候如果设置输出详细信息的话是有办法能查到实际编译成什么名字了的。更严重的问题来自调用约定:
正如上文中提到的,C++的成员函数采用__thiscall的调用约定。所谓调用约定,是指在调用函数时如何传递参数,用什么顺序传递参数,以及由谁来负责清理堆栈的约定。__thiscall这个调用约定是不被托管程序的[DllImport]属性支持的。
当然不排除一些拐弯抹角的方法是能调用的。即便如此也是极其不推荐的做法。
参考资料: http://baike.baidu.com/view/1276580.htm?fr=ala0_1_1
展开全部
基本上回答是调不了,原因来自引用名和调用约定两方面。这个需要从VC++导出类的原理说起。
类从本质上来说是数据结构和封装的操作两部分。数据结构定义在头文件当中,编译的时候就可以访问到;而成员函数是从DLL中导出的。导出C++类库的时候,这些函数名字会按照编译器的标准做一个扩展,比如说
class B{
int Operator(int a, int b);
};
里面的Operator这个成员函数,实际上会被编译成类似于这样的一个函数:
int __thiscall B_Operatorxxxxxx(B* _this, int a, int b);
(__thiscall这个关键字其实是C++里没有的)
注意到名字后面增加了一些像乱码一样的东西,这是C++编译器根据后面的参数列表自动生成的一个后缀。因为这个后缀的存在,相同名字不同参数的函数和成员函数才可以一起存在在代码里(即所谓的重载)。
这也就是说,想要调用C++类库里的函数的话,至少要知道编译器把这个函数编译成了什么名字,但实际上不同的编译器编译出来的结果都不一样。
其实这也算不上什么问题,编译的时候如果设置输出详细信息的话是有办法能查到实际编译成什么名字了的。更严重的问题来自调用约定:
正如上文中提到的,C++的成员函数采用__thiscall的调用约定。所谓调用约定,是指在调用函数时如何传递参数,用什么顺序传递参数,以及由谁来负责清理堆栈的约定。__thiscall这个调用约定是不被托管程序的[DllImport]属性支持的。
类从本质上来说是数据结构和封装的操作两部分。数据结构定义在头文件当中,编译的时候就可以访问到;而成员函数是从DLL中导出的。导出C++类库的时候,这些函数名字会按照编译器的标准做一个扩展,比如说
class B{
int Operator(int a, int b);
};
里面的Operator这个成员函数,实际上会被编译成类似于这样的一个函数:
int __thiscall B_Operatorxxxxxx(B* _this, int a, int b);
(__thiscall这个关键字其实是C++里没有的)
注意到名字后面增加了一些像乱码一样的东西,这是C++编译器根据后面的参数列表自动生成的一个后缀。因为这个后缀的存在,相同名字不同参数的函数和成员函数才可以一起存在在代码里(即所谓的重载)。
这也就是说,想要调用C++类库里的函数的话,至少要知道编译器把这个函数编译成了什么名字,但实际上不同的编译器编译出来的结果都不一样。
其实这也算不上什么问题,编译的时候如果设置输出详细信息的话是有办法能查到实际编译成什么名字了的。更严重的问题来自调用约定:
正如上文中提到的,C++的成员函数采用__thiscall的调用约定。所谓调用约定,是指在调用函数时如何传递参数,用什么顺序传递参数,以及由谁来负责清理堆栈的约定。__thiscall这个调用约定是不被托管程序的[DllImport]属性支持的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
直接调用是不行的。
有两个方法可以折中进行。
1.将c++编译的a.dll转成 com组件。 然后使用 regsvr32 命令注册到系统中就可以使用了。
2.将a.dll的算法实现不用class的方式实现,改成方法。这样可以使用P/Invoke 技术来实现。
有两个方法可以折中进行。
1.将c++编译的a.dll转成 com组件。 然后使用 regsvr32 命令注册到系统中就可以使用了。
2.将a.dll的算法实现不用class的方式实现,改成方法。这样可以使用P/Invoke 技术来实现。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
不知道楼主用没用过.net里的Interop?我觉得可以先用C++写一个类来引用a.dll里的class b,然后再用C#来调用这个C++类里的对象并实例化,应该可以完成这个东西。
参考资料: http://blog.csdn.net/starlee/article/details/2864588
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你试一下 添加一个引用a.dll
然后在命名空间上加上using a;
然后就可以使用class b了
然后在命名空间上加上using a;
然后就可以使用class b了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询