为了隐藏函数的实现,我通常编写以下C ++代码并将我的函数公开为'interfaces'
// the interface to expose
class ICalcService
{
public:
virtual double Multiple(double a, double b) const = 0;
};
// the implementation of the interface
class CalcService final : public ICalcService
{
virtual double Multiple(double a, double b) const override
{
return a * b;
}
};
// expose the 'CreateCalcService' to mydll.dll as C function
extern "C" __declspec(dllexport) void CreateCalcService(void** obj)
{
*obj = new CalcService();
}
C ++中的典型用法是
// typical way to consume the interface in C++
void test_cpp_code()
{
ICalcService* calc;
CreateCalcService(reinterpret_cast<void**>(&calc));
cout << calc->Multiple(15, 23) << endl;
}
现在我想用C#代码来消费它。经过一段时间的研究,我写了下面的代码
using System.Runtime.InteropServices;
class Program
{
interface ICalcService
{
double Multiple(double a, double b);
}
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private extern static void CreateCalcService(out object obj);
static void Main(string[] args)
{
object o;
CreateCalcService(out o);
var calc = o as ICalcService;
calc.Multiple(14, 29);
}
}
但它不会像我预期的那样工作。相反,异常是在CreateCalcService(out o)
行抛出。
托管调试助手'InvalidVariant'在'xx \ xx \ myloader.vshost.exe'中检测到问题。 附加信息:在从非托管VARIANT到托管对象的转换过程中检测到无效的VARIANT。将无效的VARIANT传递给CLR可能会导致意外的异常,损坏或数据丢失。 如果存在此异常的处理程序,则可以安全地继续该程序。 myloader.exe中出现未处理的“System.Runtime.InteropServices.InvalidOleVariantTypeException”类型异常 附加信息:指定的OLE变体无效。
有人可以让我知道这是什么问题以及如何使其发挥作用?例如错误的C#dllimport签名。
提前致谢!
答案 0 :(得分:0)
不,你不能直接调用这样的C ++接口。有几种选择。
1)用C语言包装C ++代码。
// expose the 'CreateCalcService' to mydll.dll as C function
extern "C" __declspec(dllexport) void CreateCalcService(void** obj)
{
*obj = new CalcService();
}
extern "C" __declspec(dllexport) double Multiple(void* obj, double a, double b)
{
ICalcService calc = (ICalcService)obj;
calc->Multiple(a, b);
}
使用C#代码:
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private extern static void CreateCalcService(out IntPtr obj);
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private extern static double Multiple(IntPtr obj, double a, double b);
static void Main(string[] args)
{
IntPtr calc;
CreateCalcService(out handle);
Multiple(calc, 14, 29);
}
2)编写C ++ / CLI包装器。
答案 1 :(得分:0)
它无效。 C ++接口(只是class
)与C#interface
不同。您不能将C ++对象的实例类型转换为C#接口。
答案 2 :(得分:0)
private extern static void CreateCalcService(out object obj);
param是错误的,它不能是object.Try the byte []。比如
byte[] mac = new byte[16];
private extern static void CreateCalcService(mac);