2012-05-03 1 views
4

연구 및 실험이 끝난 후에도 외부 라이브러리에서 관리되지 않는 함수에 액세스 할 때 발생하는 문제를 파악할 수 없습니다 ..dll을 가져 오기위한 C# 래퍼 "보호 된 메모리를 읽거나 쓰려고했습니다."

빠른 관련 backstory : 나는 USB를 통해 시스템에 연결되지만 직렬 포트를 가상화하는 외부 측정기를 구동하기 위해 Visual C++에서 응용 프로그램을 작성했으며 이상한 출력 동작을 감지하고있었습니다. 스스로를 입증하기 위해 제조업체는 응용 프로그램에서 미터를 제어하기 위해 .dll을 사용하기를 원합니다. enter image description here

그래서 그것을 사용하기 위해, 나는 아마 같이 DllImport를 보았다 : 좋아,하지만 ....

나는 인 DLL 직접 참조 (제거 이름 & 경로)로이 포함 할 수 없습니다 . 내 응용 프로그램에 직접 코드를 포함하는 대신 클래스를 통해 기능에 액세스 할 수 있도록 내 어셈블리를 드라이버의 래퍼로 만들기로 결정했습니다. DUMPBIN을 수행 한 후 /를 .DLL에 수출, 나는 모든 기능에 대한 진입 점을 발견하고 만 관련 예제와 함께, 그래서 같은 C# 클래스 라이브러리를 만든 포함 :

namespace Meter 
{ 
    public class PortDrv 
    { 

     [DllImport("PortDrv.dll", EntryPoint = "SERIALNUMBER", 
      CallingConvention = CallingConvention.StdCall, 
      CharSet = CharSet.Auto)] 
     public static extern long SerialNumber(Byte Index); 

     [DllImport("PortDrv.dll", EntryPoint = "OPENPORT", 
      CallingConvention = CallingConvention.StdCall, 
      CharSet = CharSet.Auto)] 
     public static extern int OpenPort(); 

    }; 
} 

함수 프로토 타입은에서 가져온했다 자신의 샘플 VB 프로그램도

SERIALNUMBER (ByVal Index As Byte) As Long 
OPENPORT() As Integer 

그리고 사용됩니다 : 나 아직도

Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long 
Private Declare Function OpenPort Lib "PortDrv" Alias "OPENPORT"() As Integer 

그들이 나를 자신의 라이브러리를 설명 전송의 .pdf? 승인. 그래서 내 자신의 어셈블리를 컴파일 한 후, 나는 내 응용 프로그램에 대한 참조를 추가하고 다음과 같은 래퍼 액세스 :

int port_return = PortDrv::OpenPort(); 
Byte bite = 0x31; 
__int64 serial = PortDrv::SerialNumber(bite); 

을하지만 폭탄 일련 번호 검색하려는 후 : enter image description here

을 그리고 꽤 아니에요 내가 어디로 잘못 가고 있는지. 일부 함수는 올바른 정보를 반환하지만 정보가 실패하면 전달해야합니다. CharSets & CallingConventions의 모든 다른 조합을 시도했습니다. ExactSpelling을 true로 설정했습니다. 내가 잘못하고있는 것이 명백하게 드러나지 않습니까? 아니면 현재 환경에서이 라이브러리를 사용할 수 있습니까?

EDIT : 기능에 '1'을 전달한 이유는 시스템에 연결되어있는 미터가 1 개인 경우 "색인"이 1이됩니다. 2 미터가 있다면, 나는 '2'를 지나서 두 번째 것에 접근 할 수 있었다.

+0

아야. 제조업체에서. NET 래퍼 또는 .NET 환경의 샘플 코드를 제공 할 수 있다고 가정하지 않습니다. 명백한 어려움을 감안할 때 이것은 부당한 요청처럼 보이지 않습니다. –

+0

흠. 0x31이 유효한 입력입니까? – Cameron

+0

@Cameron : 나는 그렇게 믿는다. 나는 '1'& 1로 전달하려고 시도했습니다.나는 명백하게 그 성격을 진술함으로써 가능한 모든 잘못된 해석을 배제하고 싶었다. 또는 0x01을 전달해야 함을 의미합니까? –

답변

5

샘플 VB 프로그램은 당신이 준 :

Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long 

ByVal 말을하지 않습니다. VB의 기본값은 ByRef입니다. 이 부분은 오타입니까? 아니면 문제입니까? 그렇다면 SerialNumber에 서명 할 때 ref Byte라고해야합니다.

도덕 : 항상 ByRef 또는 ByVal이라고 말합니다.

+0

위의 행은 드라이버를 사용하는 샘플 프로그램에 포함되어 있습니다. 당신이 내 코드라고 생각한 것처럼 보였지만, 나는 그 코드를 그대로 그대로 뽑아 냈습니다. 프로토 타입에서 바이트는 ByVal :'SERIALNUMBER (ByVal 인덱스 By Byte) As Long '로 전달됩니다. 그게 무슨 문제 야? –

+0

서명을 ref Byte로 변경했으며 메모리 오류가 가라 앉았으나 함수는 여전히 int 및 long을 사용하여 아무 것도 반환하지 않습니다. 그 주제의 초점 이었기 때문에 당신의 답을 옳은 것으로 표시하고 싶지만, 내 이슈가 아직 사라지지 않았기 때문에 지금 당장 공개하고 싶습니다. –

+0

기본적으로 일치해야합니다. 그래서 그들 중 하나가 틀렸어 야합니다. – Ben

관련 문제