2014-11-14 6 views
2

네트워크에서 RFID 판독기에 액세스하기 위해 제조업체에서 제공하는 ANSI C 라이브러리를 (P /) 호출합니다. 이 수동으로 플랫폼을 x86으로 설정하면 .NET Framework 버전 2.0에서 4.5까지 완벽하게 작동합니다..NET Framework에서 네이티브 ANSI C 라이브러리> = 4 (64 비트 기준)

반면 플랫폼을 64 비트로 설정하면 .NET Framework 버전 < = 3.5에서만 작동합니다. 내가 얻는 오류 코드는 "InvalidHandle"로 정의됩니다. 여기서 핸들은 독자가 라이브러리를 식별 할 수 있도록 주어진 int입니다. 프레임 워크 버전이 네이티브 라이브러리에 어떤 영향을 미칠 수 있는지, 특히 64 비트 플랫폼에서만 그렇습니다.

비록 내가 그것이 관련성이 있는지 확실하지 않지만, 내가 보았던 것 : - 실패의 경우, 핸들은 길이가 10 자리이며 때로는 양수이며 때로는 음수 일 수도있다. - 성공의 경우 , 핸들은 항상 9 자리이며, 항상 양수입니다.

이 관찰에 기반하여 다른 데이터 유형 (int, uint, long, ulong)을 성공없이 (그리고 같은 동작으로) 시도했습니다. 1. 초기화 (I가에서 핸들을 얻을) 2. SetChannel (매개 변수로 바이트 소요) 3 :

구성 요소의 "설정"

은 여러 단계 (메서드 호출)으로 구성되어 있습니다. SetAddress (매개 변수로 IP 및 포트를 포함하는 연결 문자열을 사용함) 4. Open() 참고 : 이러한 모든 메서드는 핸들을 int 매개 변수로 사용합니다. 메소드 SetAddress가 실패하기 때문에 Init 및 SetChannel도 매개 변수로 핸들을 사용하지만 그렇지 않으면이 이론을 지원하는 증거를 찾지 못했지만 문자열과 관련이있을 것으로 판단됩니다.

불행히도 문서가 존재하지 않습니다.

모든 아이디어를 매우 높이 평가합니다. 추가 정보가 필요하면 알려 주시면 감사하겠습니다.

감사합니다,

파스칼 BLUEBOXLib.h 파일에서

[DllImport("/x64/BLUEBOXLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
static extern int BLUEBOX_Init(out int Handle); 

[DllImport("/x64/BLUEBOXLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
static extern int BLUEBOX_SetAddress(ref int Handle, byte Address); 

[DllImport("/x64/BLUEBOXLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
static extern int BLUEBOX_SetChannel(ref int Handle, String Channel, String Settings); 

발췌 :

BLUEBOXLib_API BLUEBOX_ErrorCodes __stdcall BLUEBOX_Init (BLUEBOX_Handle *Handle); 

BLUEBOXLib_API BLUEBOX_ErrorCodes __stdcall BLUEBOX_SetChannel (BLUEBOX_Handle *Handle, char *Channel, char *Settings); 

BLUEBOXLib_API BLUEBOX_ErrorCodes __stdcall BLUEBOX_SetAddress (BLUEBOX_Handle *Handle, unsigned char Address); 

typedef int BLUEBOX_Handle; 
문제가
+0

아마도 해당 라이브러리는 순수하게 네이티브가 아니며 구현 세부 사항으로 일부 .NET 코드를 실행하게됩니다. 사용할 때 사용하는 DLL을 열거하고 작동하지 않을 때 차이점을 확인하고 그 중 하나에 .NET 메타 데이터가 있는지 확인해 볼 가치가 있습니다. –

+1

일부 매개 변수가 포인터 크기 (예 : C# 서명의 IntPtr) 여야합니다. 'BLUEBOX_Handle' 데이터 타입의 정의를 보여 주면 이것을 확인할 수 있습니다. –

+0

@BenVoigt 감사합니다. BLUEBOX_Handle의 정의를 추가했습니다. 64 비트 아키텍처의 경우, 이미 시도한 ulong과 IntPtr의 차이가 없어야합니다. 맞습니까? – Pascal

답변

3
typedef int BLUEBOX_Handle; 

하나가되지 않기 때문에 당신이 고칠 수 귀하의 코드에 나타납니다. 핸들을 구현하는 방법은 여러 가지가 있지만 기본적으로 두 가지 범주로 구분됩니다. 내부 배열에 대한 간단한 인덱스 또는 일반 포인터입니다. "10 자리 길이, 때로는 양수, 때로는 음수"가 표시되면 포인터에 대해 99 % 확률입니다.

포인터가 64 비트 모드에서 8 바이트를 차지하면 에 맞지 않습니다. 그리고 예, 가끔 은 여전히 ​​으로 작동합니다. 운영 체제와 테스트 프로그램의 단순성에 달려 있습니다. Vista 또는 Win7의 x64 버전에서는 64 비트 포인터가 우연히 32 비트 값에 여전히 들어갈 수 있으며 할당은 하위 2GB 주소 범위에서 자주 발생합니다. 당신은 Win8에서 성공할 확률이 전혀 없으며, .NET 3.5에서 작동하는 것처럼 보일 수도 있습니다. 그리고 네, 네거티브 값은 C 코드가 실제 포인터 타입으로 핸들을 캐스팅 할 때 부호 확장을 할 것이므로 쓰레기 포인터 값을 생성하기 때문에 작동하지 않을 것입니다.

이 버그를 해결할 수 없으며 공급 업체가 해결해야합니다. 그들은 typedef를 void*으로 변경해야합니다. 이제 IntPtr을 사용할 수 있습니다. 그들에게 전화하십시오. 응답하지 않는 경우이 코드를 다른 32 비트 도우미 프로세스에서 실행하는 것이 좋습니다.

+0

그는 또한 자신의. NET 응용 프로그램에서'/ LARGEADDRESSAWARE'를 사용하지 못하게 할 수도 있습니다. –

+0

물론 64 비트 앱에서는 그다지 중요하지 않습니다. –

+0

Microsoft에 따르면 LAA가없는 64 비트 코드는 2GB의 주소 공간 만 사용합니다. –