开发者

Call an old C++ function from .NET for non-primitive data type

I have an old C++ function that I must use in my .NET application. Every time I tried to call and cast the pointer back to the class, I receive an error indicating that I attempted to read or write into 开发者_Python百科protected memory. Could someone help me to point me to the right direction please. Here's the codes:

typedef struct
{
 char szModel[32];
 float fSpeed;
 float fData[20];
} CAR, far *LP_CAR; 

//Function prototype
int FAR PASCAL Process(char szModel[32], LP_DATA pCar); 

And my .NET codes:

[DllImport("Unmanaged.dll", CharSet = CharSet.Ansi)]
public static extern int Process(string model, IntPtr data);

//****** Implementation **********

public class ManagedClass
{
   public string szModel = new string(new char[32]);
   public float fSpeed;
   public float[] fData = new float[20];
}

ManagedClass aCar = new ManagedClass();
IntPtr ptr = Marshal.AllocHGlobal(Marshal.Sizeof(aCar));
Marshal.StructureToPtr(aCar, ptr, false);
Process(aCar, ptr);

ManagedClass model2 = (ManagedClass)Marshal.PtrToStructure(ptr, 
                                                           typeof(ManagedClass));


This is how I would do it:

C++

typedef struct
{
  char szModel[32];
  float fSpeed;
  float fData[20];
} CAR, far *LP_CAR; 

extern "C" {
    int __stdcall Process(char *szModel, CAR &lpCar); 
}

C#

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct CAR
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string szModel;
    float fSpeed;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20)]
    float[] fData;
}

[DllImport("Unmanaged.dll", CharSet = CharSet.Ansi)]
static extern int Process(
    string model, 
    ref CAR data
);

Call it as follows:

CAR data;
Process(@"test", ref data);


Try declaring your "CAR" ManagedClass structure like this:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct CAR
{
    [MarshalAs(UnmanagedType.AnsiBStr, SizeConst=32)]
    public string szModel;
    float fSpeed;
    [MarshalAs(UnmanagedType.LPArray, SizeConst=20, MarshalTypeRef=typeof(float[]))]
    float[] fData;
}

Then invoke your native method with:

CAR myCar;

Process( model, ref myCar );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜