C ++를 마샬링하는 방법 C ++/CLI 구조물의 구조물 배열에서 관리되지 않는 C ++
문제
구조물 배열을 관리되지 않는 C ++ DLL로 전달하기 위해 올바른 구문을 찾고 있습니다.
내 DLL 가져 오기는 이렇게 불립니다
#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool _Validation(/* array of struct somehow */);
내 클라이언트 코드에서 나는 가지고 있습니다
List<MyStruct^> list;
MyObject::_Validation(/* list*/);
나는 System :: Runtime :: interopservices :: Marshal은 이와 같은 일을하는 데 유용한 방법이 많이 있지만 어느 것이 사용되어야하는지 잘 모르겠습니다.
해결책
structlayout.sequential을 사용하여 관리되지 않은 구조물의 관리 버전을 만듭니다 (동일한 순서로 물건을 넣어야합니다). 그런 다음 관리 기능 (예 : 검증 (mystruct [] pstructs)으로 전달하는 것처럼 전달할 수 있어야합니다.
예를 들어, 우리의 기본 기능 에이 프로토 타입이 있다고 가정 해 보겠습니다.
extern "C" {
STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems);
}
그리고 자연 마이 스트럭은 다음과 같이 정의됩니다.
struct MYSTRUCT
{
int a;
int b;
char c;
};
그런 다음 C#에서는 다음과 같이 관리되는 구조물의 버전을 정의합니다.
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MYSTRUCT
{
public int a;
public int b;
public byte c;
}
그리고 다음과 같이 관리되는 프로토 타입 :
[System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")]
public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems);
그런 다음 다음과 같이 MyStruct Structs 배열을 전달하는 함수를 호출 할 수 있습니다.
static void Main(string[] args)
{
MYSTRUCT[] structs = new MYSTRUCT[5];
for (int i = 0; i < structs.Length; i++)
{
structs[i].a = i;
structs[i].b = i + structs.Length;
structs[i].c = (byte)(60 + i);
}
NativeMethods.fnStructInteropTest(structs, structs.Length);
Console.ReadLine();
}
다른 팁
당신이 사용할 수있는 Marshall.structureToptr intptr을 얻으려면 기본 MyStruct* 배열로 전달 될 수 있습니다.
그러나 목록에서 직접 수행하는 방법을 잘 모르겠습니다. 나는 이것을 배열로 변환하고 기본 코드로 전달하기 전에 PIN_PTR (GC가 메모리를 움직이지 않도록)을 사용해야한다고 생각합니다.
제휴하지 않습니다 StackOverflow