2013-05-24 2 views
1

내가 사용하고있는 API는 다음과 같이이 부호없는 long을 마샬링해야합니까? 그것의</p> <pre><code>int simpletran(LPSTRUCT req) { printf("%d", req->length); } typedef unsigned long ULONG; typdef struct _st { ULONG length; }STRUCT, *LPSTRUCT; </code></pre> <p>내 C# 버전 :

[DllImport(LINUXLIB, CallingConvention=CallingConvention.Cdecl)] 
public static extern simpletran(STRUCT req); 

class STRUCT 
{ 
    public UInt32 length; 
} 
STRUCT st = new STRUCT(); 
st.length = (UInt32)100; 
simpletran(st); 

내가 같은 -31245665 일부 긴 음의 값을 얻을 관리되지 않는 함수를 호출

!

Linux 컴퓨터에서 C# mono를 사용하고 있습니다.

+0

으로 전화를 걸어 할당 된 메모리를 확보하십시오. UInt64를 사용해 보셨습니까? – ghord

+0

예 내가 한 일을하지 않습니다 !! : – infinitloop

답변

1

나는 이것을 테스트하지 않았으므로 약간의 변경이 필요할 수 있지만 여기서는 내가 보지 못한 것이 있습니다. 다음과 같이

첫째, STRUCT 선언한다 : 우리는 개체의 메모리 레이아웃을 알고 그래서 class에서 struct로 변경하고 C 코드가 기대 것과 일치

struct STRUCT 
{ 
    public UInt32 length; 
} 

알 수 있습니다. 더 고려의 비트, 선언하고 메소드를 호출하는 쉬운 방법이 후

업데이트

, 나는 그 일을하는 또 다른 방법은 아래 원래의 대답을 떠날거야.

귀하의 P/호출 서명이 있어야한다 : 우리가 STRUCT 이후 ref STRUCTSTRUCT을 변경

[DllImport(LINUXLIB, CallingConvention=CallingConvention.Cdecl)] 
public static extern int simpletran(ref STRUCT req); 

주의는 값 타입과 C 코드는 그 구조에 대한 포인터가 필요합니다.

그리고 당신은 다음과 같이 호출 것 : 우리가 STRUCT 이후 IntPtrSTRUCT을 변경 원래

[DllImport(LINUXLIB, CallingConvention=CallingConvention.Cdecl)] 
public static extern int simpletran(IntPtr req); 

공지 사항이어야한다

STRUCT st = new STRUCT(); 
st.length = (UInt32)100; 
simpletran(ref st); 

가 값 타입과 C 코드가 필요 그 구조체에 대한 포인터.

그리고 당신은 다음과 같이 호출 것 :

STRUCT st = new STRUCT(); 
st.length = (UInt32)100; 
IntPtr ptr = Marshal.AllocHGlobal(sizeof(STRUCT)); 
Marshal.StructureToPtr(st, ptr, false); 
simpletran(ptr); 
Marshal.FreeHGlobal(ptr); 

인스턴스를 생성하고있는 구조체의 값을 저장하는 관리되지 않는 메모리 청크를 할당하는 방법을 호출 사이에 추가 단계를 추가 (Marshal.AllocHGlobal) st 값을 Marshal.StructureToPtr(...)으로 해당 메모리에 복사합니다. Marshal.FreeHGlobal

+0

내가 클래스를 사용하는 이유는 클래스가 참조에 의해 전달 되었기 때문에 (힙 할당 이후) 구조체가 값으로 전달 되었기 때문에 물론 ref를 사용할 수 있습니다. – infinitloop

+0

구조체가 될 수 있어야합니다. 클래스의 메모리 레이아웃을 제어하지 않고 structs 만 사용합니다. – mlorbetske

관련 문제