2009-12-02 4 views
1

닫힌 소스 관리되지 않는 DLL을 C++로 코딩하여 C# 솔루션에서 사용하려고 했으므로 P/Invoke를 사용하여 닫힌 소스 DLL 함수를 호출하는 래퍼 관리 DLL을 만들었습니다. 이것은 param 함수와 int 변수가 없어도 잘 작동합니다. 그러나 System.ExecutionEngineException 문자열의 문자 배열을 포함하는 매개 변수로 구조체의 배열을 사용하여 더 복잡한 함수를 실행할 때 가져옵니다. 여기에 내가 가진 무엇 :P/Invoke throw System.ExecutionEngineException

#define TARGET_LBL_SIZE (256l) 

typedef struct _tyrfdeTarget 
{ 
    TInt32 TargetID;     // integer signed 32bits 
    TCharA Label[TARGET_LBL_SIZE];  // caracter 
} tyrfdeTarget; 

TInt32 __stdcall tyrfdeGetTargets(tyrfdeTarget* pTargets); 

배열 크기가 어쨌든 SizeConst 긴하지만로 지정된 이유를 확신뿐만 아니라 걸릴 : 아래

[StructLayout(LayoutKind.Sequential)] 
public struct Target 
{ 
    public int targetID; 

    public string Label; 
} 

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTarget")] 
public static extern int GetTarget(ref Target[] targets); 

내가 DLL의 헤더 파일에서 가지고있는 정보입니다 int. 여기에 몇 가지 검색 후 내가 고치려고했다.

[StructLayout(LayoutKind.Sequential, Size = 260), Serializable] 
public struct Target 
{ 
    public int targetID; 

    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 256)] 
    public string Label; 
} 

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTargets")] 
public static extern int GetTarget(ref Target[] targets); 

하지만 여전히 문제가 있습니다. 함수가 CLR에서 사용하는 메모리의 일부를 지우는 경우이 예외가 throw 될 수 있음을 읽었습니다. 불행히도 나는 그것을 확인할 수 없다. 분명히 잘못되어 문제를 일으킬 수있는 코드가 있나요?

+0

실제로 배열을 할당하고 함수를 호출하는 예제도 게시해야합니다. 문제가있을 수 있습니다. 함수가'N '요소에 대한 포인터를 받아들이면 배열의 요소 수가 두 번째 매개 변수로 필요하지 않다는 것이 이상하게 보입니다. – arul

답변

2

흠, 귀하의 문제는 참조 Target[] targets 매개 변수라고 생각합니다. AFAIR 이것은 참조에 대한 참조이며 실제로 참조하는 것이 아닙니다.

나는이 시도 것 :

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTargets")] 
public static extern int GetTarget([Out, MarshalAs(UnmanagedType.LPArray)] Target[] targets); 

어쩌면 this article 올바른 선언을 발견하는 데 도움이

.

배열의 크기는 여기에서 명확하지 않으며 일반적으로 ref int length 매개 변수가 있으며이 매개 변수는 SizeParameterIndex 속성을 통해 MarshalAs 특성에서 참조 할 수 있습니다.

+0

[MarshalAs (UnmanagedType.LPArray)] throw하는 오류를 중지하지만 내 배열이 함수로 채워지지 않습니다. 심판이 거기에 있었던 이유가 아니 었나요? –

+0

아, 배열이 함수로 채워져 있습니다 ...이 경우 [Out] 특성을 추가해야합니다. 편집 된 코드를 사용해보십시오. – Lucero

+0

수정 된 버전이 작동합니다. 고마워, 왜 구문이 아닌지 어떤 생각 : GetTarget ([MarshalAs (UnmanagedType.LPArray)] target [] targets); –

0

1) TCharA가 16 비트인지 확인 하시겠습니까? 그렇지 않으면 사용할 whar CharSet을 지정해야한다고 생각합니다.

2) 이런 종류의 래퍼를 작성하는 것은 C++/CLI에서 훨씬 간단합니다.

+0

1 : 형식 정의가 없으므로 확실하지는 않지만 공정한 추측입니다. 2 : 이전 기사에서 : 관리되지 않는 API가 DLL로 패키지화되어 있고 소스 코드를 사용할 수없는 경우 P/Invoke가 유일한 옵션입니다. –

+0

1. 확인해보십시오. 2. 잘못 생각한 것 같습니다. C++/CLI 어셈블리를 사용하면 .h- 파일을 포함하거나 .lib 파일에 링크 할 수 있습니다. "관리되는 토지"에 계속 살고 있어야합니다. 그것은 여전히 ​​C++/CLI cde가 "P/Invoke"를 호출하는 이름을 당신에게 달려 있습니다. :-) –