2010-12-27 4 views
3

현재 C#에 독점적 인 dll (API)을 포팅하고 있으며 일부 사용 된 데이터 형식을 마샬링 할 때 몇 가지 문제가 있습니다.C#에서 int 및 long 마샬링 C#에서 int 및 long 마샬링

는 예를 들어, API 헤더 파일은 다음과 같은 유형의 정의 :

typedef unsigned int tINT; /* natural unsigned */ 
typedef signed int tINTs; /* natural signed */ 
typedef unsigned int tLONG; /* 32 bit unsigned */ 
typedef unsigned long tPTR; /* 32/64-bit pointer */ 

을 그럼 예를 들어 다음 함수 정의가 :

tINTs SomeApiFunction (const tPTR hdl, tINT param); 

나는 보통 직접으로 int을 정렬 화하고 있습니다를 C#의 int (Int32) 또는 서명되지 않은 버전입니다. API의 tLONGtINT은 동일합니다 (적어도 API의 경우). 하지만 tPTR으로는 확신 할 수 없습니다. 32 비트 int이기 때문에 지금은 uint을 C#으로 만들었지 만, long이 64 비트 시스템에서 어떻게 동작하는지 잘 모르겠습니다.

API가 32 비트 및 64 비트 시스템에서 올바르게 작동하려면 어떻게해야합니까?

이 지금했을 것입니다 :

[DllImport("api.dll")] 
public static extern int SomeApiFunction (uint hdl, uint param); 

슬프게도 API는 정말 잘 같은 내가 의도는 모든 사람 (중복) 형식 정의와 무엇인지 확실하지 않다, 문서화되어 있지 않습니다. 위에 포함 된 헤더 주석 외에도 실제 유형에 대한 정보는 없습니다.

답변

3

IntPtr으로 마샬링을 시도하십시오. IntPtr은 32 비트 시스템에서는 4 바이트이고 .Net에서는 64 비트 시스템에서 8 바이트입니다.

+0

오, 그냥 빠른 질문 : 포인터가 * unsigned * long이라는 점을 감안할 때'IntPtr' 또는'UIntPtr'을 사용해야합니까? – poke

+0

포인터 연산으로 인해 음수 값을 처리하는 데 문제가 없으면 IntPtr을 사용해야합니다. msdn docs에서 : IntPtr 형식은 CLS 규격이며 UIntPtr 형식은 그렇지 않습니다. IntPtr 형식 만 공용 언어 런타임에서 사용됩니다. UIntPtr 형식은 주로 IntPtr 형식의 아키텍처 대칭성을 유지하기 위해 제공됩니다. –

1

정확하게 기억한다면 intuint 및 기타 기본 유형이 기본 Windows API에 적합한 유형입니다.

그러나 포인터의 경우 C# 측에 IntPtr을, C/C++ 측에 void*을 사용하는 것이 가장 좋습니다.

3

이것은 C/C++ 컴파일러의 구현 세부 사항입니다. 코멘트로 가서 IntPtr로 선언해야합니다. 코드가 MSVC 컴파일러에 의해 컴파일 된 다음 64 비트 모드에서 작동하지 않을 경우 32 비트를 오래 사용합니다. 포인터를 저장할만큼 충분하지 않습니다.

+0

정확히 64 비트에서 작동하지 않는다는 것을 의미합니까? 내 예제 C# 코드 또는 전체 API (나를 놀라게하지 않습니다 tbh.)? – poke

+0

전체 API와 C# 예제도 마찬가지입니다. 해당 DLL의 미리 빌드 된 64 비트 버전이 있습니까? 당신은 일반적으로 주위를 찌를 수 있고 어떻게 지어 졌는지 알 수 있습니다. –

+0

아니요, 하나의 DLL 만 있습니다. :/ – poke