내가 관리되지 않는 Win32에서 C++ DLL의 일반적인 구조를 가지고 할당 할 수 있었던 바이트 배열의 요소잘못된 관리/비 관리 형 겸용, 동적으로 할당 된 배열
다음이 정의를 사용하여 할당 채우기 및 구조체의 할당을 해제하는 기능을 보냅니다 DLL : 기본 호출자의 잘
// The exported allocator function.
extern "C" _declspec(dllexport)
FirstElemPtrContainer *BuildStruct(int elem_count)
{
FirstElemPtrContainer *fepc_ptr = new FirstElemPtrContainer;
fepc_ptr->num_elems = elem_count;
elem_type *ary = new elem_type[fepc_ptr->num_elems];
for (int i = 0; i < fepc_ptr->num_elems; i++)
{
ary[i] = ((i + 1) * 5); // multiples of 5
}
fepc_ptr->allocd_ary = ary;
return fepc_ptr;
}
// The exported deallocator function.
extern "C" _declspec(dllexport) void
DestroyStruct(FirstElemPtrContainer *fepc_ptr)
{
delete[] fepc_ptr->allocd_ary;
delete fepc_ptr;
}
이 일을.
[StructLayout(LayoutKind.Sequential)]
public struct FirstElemPtrContainer
{
public byte num_elems;
[MarshalAs(UnmanagedType.LPArray,
ArraySubType = UnmanagedType.U1, SizeConst = 4)]
public IntPtr allocd_ary;
}
... 그래서 같이 호출 인터페이스를 설명합니다 : C#에서
, 나는 PInvoke를 통해이 같은 구조를 설명하려고public static class Imports
{
[DllImport("MyLib", CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr BuildStruct(int elem_count);
[DllImport("MyLib", CallingConvention = CallingConvention.Winapi)]
public static extern void DestroyStruct(IntPtr fepc_ptr);
}
지금 내 인터페이스 호출을 시도 :
class Program
{
const int NUM_ELEMS = 4;
static void Main(string[] args)
{
IntPtr fepc_ptr = Imports.BuildStruct(NUM_ELEMS);
if (fepc_ptr == IntPtr.Zero)
{
Console.WriteLine("Error getting struct from PInvoke.");
return;
}
FirstElemPtrContainer fepc =
(FirstElemPtrContainer)Marshal.PtrToStructure(fepc_ptr,
typeof(FirstElemPtrContainer));
//...
}
}
PtrToStructure() 호출은 수 "없습니다 원수 필드 'allocd_ary'유형 '을 오류를 제공 MyLibInvoke .FirstElemPtrContainer ': 잘못된 관리되는/관리되지 않는 형식 조합 (Int/UInt는 SysInt 또는 SysUInt와 쌍을 이루어야 함). "
호출자가 준수한다고 가정하는 특정 수의 요소를 하드 코딩 한 것을 볼 수 있습니다. 차이점을 보이지는 않지만 ArraySubType 절도 추가했습니다. 왜 유형 불일치가 불만 사항입니까?
맞습니다. 바이트 배열을 포함하도록 PInvoke 정의를 변경하라는 원래의 제안을 시도했지만 다른 오류가 발생했습니다 : "배열의 런타임 유형과 메타 데이터에 기록 된 하위 형식간에 불일치가 발생했습니다." 나는 이미 마샬을하고 있었다. 코드()를 복사하고 있었기 때문에 문자 그대로 내가했던 마샬 (MarshalAs()) 잡담을 주석 처리했다. 그런 다음 나는 여기로 돌아와 내가 방금 한 것과 똑같은 것을 제안했음을 알았다. – Buggieboy
@Buggieboy 당신을 잘못 이끌어 준 것에 대해 사과드립니다. 나는 충분히 처음으로 질문을 자세히 읽지 않았다. 하지만 국제 대회에 관해서는 어떻습니까? 명시 적으로 C++ 코드에서 설정하지 않으면 'Cdecl'이됩니다. –
David - 글쎄, Visual Studio 2005에서 C++ Win32 DLL 프로젝트를 만들었고 내 함수 정의 앞에 "extern"C "_declspec (dllexport)"이 있으면 아무 것도 알려줍니다. "CallingConvention.Winapi"는 아무 것도 해를 끼치 지 않는 것처럼 보였으므로 나는 그대로 두었다. – Buggieboy