아래와 같이 두 개의 C++ 구조체가 있습니다. C#에서 DLL 메서드를 호출 할 때 구조체를 가져와야합니다.중첩 된 구조체를 정렬하십시오.
예를 들어, C에서 아래를 정의 할 수 있습니다 ++ 코드 :
struct A
{
int count;
struct B;
}
struct B
{
char* id;
char* name;
}
C++ 코드는 아래의 방법
A* GetData();
나는 C#을에서 호출해야하는 방법을 돌려 다음 서명이 :
IntPtr GetData();
이 메소드는 struct A, id 및 C#에서 구조체 B.
에서 이름 난 클래스로 이러한 구조를 정의
[StructLayout(LayoutKind.Sequential)]
class A
{
public int count;
public IntPtr B;
}
[StructLayout(LayoutKind.Sequential)]
class B
{
public string id;
public string name;
}
전 C#에서 호출하는 C++ DLL을 만들었습니다.
중첩 된 구조에서 데이터를 읽으려고하면 읽기 위반 오류가 발생합니다.
어떻게 중첩 된 구조체를 마샬링하여 C# 방식으로 읽을 수 있습니까? 어떻게 ID와 이름을 가진 구조체 B의 멤버에 액세스 할
[DllImport("Win32Project.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern IntPtr GetData();
A setting = new A();
setting.B = new IntPtr();
IntPtr deviceSettingptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(A)));
IntPtr settingsInfoptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(B)));
Marshal.StructureToPtr(setting, deviceSettingptr, false);
Marshal.StructureToPtr(setting.B, settingsInfoptr, true);
setting.B= settingsInfoptr;
deviceSettingptr = GetData();
setting = (A)Marshal.PtrToStructure(deviceSettingptr, typeof(A));
B info = (B)Marshal.PtrToStructure(setting.B, typeof(B));
Console.WriteLine(string.Format("Setting count={0}", setting.count));
Console.WriteLine(string.Format("Setting id={0}, Setting name={1}", info.id, info.name));
아래로
내 C# 코드는?
잠깐,'A.b'는'B' 또는'B'에 대한 포인터입니까? – Luaan
A.B 멤버는 포인터가 아니라 구조체입니다. 대신 B로 선언해야합니다. B의 문자열은 매우 중요한 메모리 관리 문제이며 누군가는 다시 릴리스해야합니다. pinvoke marshaller는이를 수행 할 수 없으므로 IntPtr로 선언하고 Marshal.PtrToStringAnsi()를 사용해야합니다. 어떻게 메모리를 공개할까요, 행운을 빈다. GetData()의 반환 값에 대해서도 똑같은데, 이것은 매달린 포인터라는 높은 확률입니다. C++ 코드를 먼저 개선하고, 그대로 사용할 수 없습니다. –
구조체 B의 문자열을 IntPtr로 선언하고 아래에서 사용하여 데이터를 가져 왔습니다. string id = Marshal.PtrToStringAnsi (info.id); 하지만 빈 문자열이 반환됩니다. –