2012-11-27 3 views
0

먼저이 질문에 대한 답변을 찾기 위해 고가 및 저질 검색을 수행했으며 C++ 프로그래머가 아닌 모든 것이 헛 스럽다 고합니다. 프로그래밍은 나를위한 취미 일뿐입니다.SafeArrayTypeMismatchException 비 관리 C++ DLL을 사용하려고 시도하는 중

C# winforms 프로젝트에서 Visual Studio 2010 Ultimate을 사용하고 있습니다.

문제는 관리되지 않는 DLL (Bo Haglund의 Double Dummy Solver)에서 함수를 사용하려고한다는 것입니다. 그의 readme는 도움이되지 않고 놀랍게도 (즉, 아니오) 자신의 DLL을 사용하는 방법에 대한 기사가 있습니다.

내가 사용하고자하는 DLL의 함수 프로토 타입이 있습니다.

extern "C" __declspec(dllimport) int __stdcall CalcDDtablePBN(struct ddTableDealPBN tableDealPBN, struct ddTableResults * tablep); 

포인터에 대해서는 잘 모르지만 C#에서는 "ref"를 사용한다고 생각했습니다.

CalcDDtable

CalcDDtable 모두 20 트럼프의 슈트/선언자 핸드 조합 초기 52 개 카드 이중 더미 값을 계산한다 :

여기서 함수 그의 README이다.

CalcDDtable을 호출하기 전에 "ddTableResults"유형의 구조를 선언해야합니다. CalcDDtable은 상태 정수를 반환하고 "no fault"는 DLL이 "ddTableResults"유형 구조에 이중 더미 점수를 제공 함을 의미합니다. 상태 코드 :
1 = 오류가 없습니다. 다른 상태 코드는 SolveBoard 상태 코드와 동일한 오류입니다.

구조 "ddTableDeal"은 분석 할 거래 카드를 정의합니다. struct ddTableDeal { 부호없는 int 카드 [4] [4];/* 첫 번째 인덱스는 손이고, 두 번째 인덱스는 SolveBoard의 deal.remainCards와 같은 코드입니다. */ };

struct ddTableResults { /* For each combination trump suit/declarer hand, the DLL provides the double dummy score. */ 
    int resTable[5][4]; /* 1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs, 4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */ 
}; 

CalcDDtablePBN

거래 정보의 나머지 카드는 PBN 텍스트 형식으로 제공됩니다 CalcDDtablePBN에서

, SolveBoardPBN에 ​​대한 위의 설명을 참조하십시오. 그렇지 않으면 CalcDDtablePBN은 CalcDDtable과 동일합니다. 여기

[DllImport("dds.dll")] 
public static extern int CalcDDtablePBN(DDTableDealPBNStruct tableDealPBN, ref DDTableResultsStruct tablep); 

내 구조체은 다음과 같습니다 :

public struct DDTableDealPBNStruct 
{ 
    public char[] cards; 

    public DDTableDealPBNStruct(char[] pbnCards) 
    { 
     cards = pbnCards; 
    } 
} 

public struct DDTableResultsStruct 
{ 
    public short[,] resTable; /* 1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs, 4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */ 
} 

그리고 이것은 내가 함수를 호출하는 방법입니다

const string _dealPBN = "N:QJT..AJ76.AKJ765 AK64.AKJ7654..98 32.T932.KQ32.T43 9875.Q8.T9854.Q2"; 
DDTableDealPBNStruct tdPBN = new DDTableDealPBNStruct(_dealPBN.ToCharArray()); 
DDTableResultsStruct results = new DDTableResultsStruct(); 
results.resTable = new short[5, 4]; 
CalcDDtablePBN(tdPBN, ref results); 
을 다음과 같이

struct ddTableDealPBN { 
    char cards[80]; 
}; 

나는 기능을 가져

프로그램을 실행할 때 다음과 같은 오류 메시지가 나타납니다.

SafeArrayTypeMismatchException이 처리되지 않았습니다. 지정된 배열이 예상 된 유형이 아닙니다.

어떤 어레이가 좋지 않다고 언급하지 않지만 짧은 [5,4] 어레이라고 추측합니다. 나는 다른 [MarshalAs (UnmanagedType.blah)] 옵션을 사용하지 않으려 고 노력했다. 아무도 내가 뭘 잘못하고 있다고 말할 수 있습니까? 나는 솔직히 엉망이다.

나는 int, uint, short, Int16 등의 다른 배열 유형을 다시 시도했지만 아무런 소용이 없습니다. 내가 틀렸고 그것이 불평하고있는 char [] 배열이 아니라면?

미리 감사드립니다.

답변

1

구조체의 레이아웃을 설명해야합니다.

[StructLayout(LayoutKind.Sequential)] 
public struct DDTableResultsStruct 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 
    public int[] resTable; 
} 

배열은 2 차원이라고 할 수있는 방법이있을 것 같지 않습니다, 그래서 난 그냥 1 차원 인 것처럼 배열의 전체 크기를 부여했습니다. (C에서 다차원 배열은 연속적으로 메모리에 배치됩니다.) 요소 유형은 short이 아닌 int이 아니라 32 비트입니다. 다른 구조체에 대해서도 동일한 작업을 수행해야합니다.

(테스트되지 않은 코드입니다.)

+0

은 나뿐만 아니라 (80)의 고정 길이 문자 배열을 변경하면 잘 작동, 당신은 ymett 감사드립니다. – cjk84

관련 문제