Вызов старой функции C ++ из .NET для непримитивного типа данных - PullRequest
3 голосов
/ 23 марта 2011

У меня есть старая функция C ++, которую я должен использовать в своем приложении .NET. Каждый раз, когда я пытался вызвать и привести указатель обратно в класс, я получаю сообщение об ошибке, указывающее, что я пытался читать или писать в защищенную память. Может ли кто-нибудь помочь мне указать мне правильное направление, пожалуйста. Вот коды:

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); 

И мои .NET коды:

[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));

Ответы [ 2 ]

1 голос
/ 23 марта 2011

Вот как я бы это сделал:

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
);

Назовите это следующим образом:

CAR data;
Process(@"test", ref data);
1 голос
/ 23 марта 2011

Попробуйте объявить структуру ManagedClass "CAR" следующим образом:

[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;
}

Затем вызовите свой собственный метод с помощью:

CAR myCar;

Process( model, ref myCar );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...