[英]calling c++ function from c# with a reference type as parameter
int Set(CANMsg &CANObj)
I have to call the method above, from c#. 我必须从c#调用上面的方法。 Untill now i have defined a wrapper :
直到现在我已经定义了一个包装器:
extern "C" __declspec(dllexport) int SetWrapper(CANMsg CANObj);
CANMsg CANObj --- is this parameter ok or should i use CANMsg *CANObj ? CANMsg CANObj ---这个参数是ok还是我应该使用CANMsg * CANObj?
and here i implement the wrapper: 在这里我实现了包装器:
extern "C" __declspec(dllexport) int SetWrapper(CANMsg CANObj)
{
return Set(CANObj);
}
I am creating this wrapper because this is an overloaded version of the function and i had to make a difference somehow. 我正在创建这个包装器,因为这是函数的重载版本,我不得不以某种方式有所作为。
Here is the CANMsg class: 这是CANMsg类:
class CANMsg
{
public:
CANMsg();
~CANMsg();
void AddRef() const;
void Release() const;
unsigned int MsgId;
unsigned int DLC;
unsigned int Handle;
unsigned int Interval;
unsigned int TimeStamp;
unsigned char Data0;
unsigned char Data1;
unsigned char Data2;
unsigned char Data3;
unsigned char Data4;
unsigned char Data5;
unsigned char Data6;
unsigned char Data7;
protected:
mutable int refCount;
};
Now, in C# i have the following : 现在,在C#中我有以下内容:
[StructLayout(LayoutKind.Sequential)]
public class CANmsg
{
public int MsgId;
public int DLC;
public int Handle;
public int Interval;
public int TimeStamp;
public char Data0;
public char Data1;
public char Data2;
public char Data3;
public char Data4;
public char Data5;
public char Data6;
public char Data7;
}
and the import is like this : 和导入是这样的:
[DllImport("engine.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int SetWrapper(IntPtr canMSGObject);
I am a bit confused about that CANMsg object, am I declaring it ok as an IntPtr, is the marshal ok, or the types ? 我对CANMsg对象有点困惑,我是否认为它可以作为IntPtr,是元帅,还是类型? If i let it like so, with the IntPtr, what kind of instantiation should i perform there?
如果我喜欢它,使用IntPtr,我应该在那里执行什么样的实例化? If i send a CANMsg object, i get an error regarding some invalid arguments.
如果我发送一个CANMsg对象,我得到一些关于一些无效参数的错误。
Let me know if you need some more details about this. 如果您需要更多详细信息,请与我们联系。
When I see your C++ class definition, I ask myself "what happens in the constructor and the destructor?" 当我看到你的C ++类定义时,我会问自己“构造函数和析构函数中会发生什么?” and "what do
AddRef()
and Release()
do?" 和“
AddRef()
和Release()
做什么?” These are important questions because you can't simply project data from a C# object onto that IntPtr and hope for the best. 这些都是重要的问题,因为您不能简单地将数据从C#对象投影到该IntPtr上,并希望获得最佳效果。 Instead, you should think about making a helper dll that does this work for you.
相反,你应该考虑制作一个帮助你的助手dll。 You might need methods something like this:
你可能需要这样的方法:
public ref class MyLibraryHelper {
public:
IntPtr MakeCANMsg() { return gcnew IntPtr(new CANMsg()); }
void DestroyCANMsg(IntPtr msgPtr) {
CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
if (msg) delete msg;
}
void ProjectTo(CSharpCANMsg ^csh, IntPtr msgPtr)
{
CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
if (!msg) return;
msg->MsgId = csh->get_MsgId();
// etc
}
void ProjectFrom(IntPtr msgPtr, CSharpCANMsg ^csh)
{
CANMsg *msg = reinterpret_cast<CANMsg *>(msgPtr.ToPointer());
if (!msg) return;
csh->set_MsgId(msg->MsgId);
// etc
}
}
My C++/CLI is rusty, so expect some issues. 我的C ++ / CLI很生疏,所以期待一些问题。 If this looks like hand-marshalling, well, it is because given the class that you've exposed, it seems like you need it.
如果这看起来像是手工编组,那么,这是因为根据你所暴露的课程,你似乎需要它。
Now honestly, you probably don't want this. 老实说,你可能不想要这个。 Really, you want a C++/CLI class that constructs a CANMsg and keeps it as a private member and then maps .NET properties onto the lower level object.
实际上,您需要一个C ++ / CLI类来构造一个CANMsg并将其保存为私有成员,然后将.NET属性映射到较低级别的对象上。 This type of class will have to be disposable and the
!ClassName()
destructor will be responsible for deleting the underlying object. 这种类必须是一次性的,而
!ClassName()
析构函数将负责删除底层对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.