2011-08-10 4 views
1

DLL에서 관리되는 C# 메서드를 호출하는 관리되지 않는 C++ 함수가 있습니다. C# 메소드의 목적은 (C++ 호출자가 할당 한) 바이트 배열을 가져 와서 배열을 채우고 리턴하는 것입니다. 배열을 C# 메서드로 가져올 수 있지만 C++ 함수로 돌아 가면 채워진 데이터가 손실됩니다.C++ <--> 마샬링 된 바이트 배열을 수정하십시오.

C# DLL 방법 :

// bytes[] has been already allocated by its caller 
short int SimGetBytesP2P(unsigned char bytes[]) 
{ 
    unsigned short int numBytes = 0; 
    bytes[0] = 'x'; 
    bytes[1] = 'y'; 
    bytes[2] = 'z'; 
    // bytes[] are {'x', 'y', 'z'} here 
    guiPtr->GetBytesFromBlaster(bytes, &numBytes); 
    // bytes[] SHOULD be {'a', 'b', 'c'} here, but they are still {'x', 'y', 'z'} 
    return(numBytes); 

}

나는 그것을 믿지 : DLL을 호출

// Take an array of bytes and modify it 
public ushort GetBytesFromBlaster([MarshalAs(UnmanagedType.LPArray)] byte[] dataBytes) 
{ 
    dataBytes[0] = (byte)'a'; 
    dataBytes[1] = (byte)'b'; 
    dataBytes[2] = (byte)'c'; 
    return 3; 
} 

C++ 기능 지금,이 프로세스를 디버깅하는 내 테스트 코드는 C# 포인터를 새로운 관리 배열로 바꾸고 원래 배열을 수정하는 것과 관련이 있습니다. "ref"수정 자 등을 사용하여 여러 변형을 시도했지만 운이 없습니다. 또한이 데이터는 널로 끝나는 문자열이 아닙니다. 날 % Y이트는 널 (NULL) 종료가 아닌 원시 1 바이트 값입니다.

누구든지이 문제에 대해 알려주시겠습니까? 감사!

스튜어트

답변

4

자신을 마샬링 할 수 있습니다. C# 함수가 IntPtr 유형의 값으로 매개 변수를 허용하도록하십시오. 또한 배열 길이를 나타내는 두 번째 매개 변수입니다. 특수한 마샬링 특성이 필요하거나 필요하지 않습니다.

그런 다음 Marshal.Copy를 사용하여 관리되지 않는 포인터의 배열을 할당 한 관리 바이트 [] 배열로 복사합니다. 일을 마친 다음 완료되면 마샬을 사용합니다. 복사하여 C++ 관리되지 않는 배열로 다시 복사합니다.

이 특정 오버로드를 사용하면 시작할 수 있어야합니다 기본 하나 ISN 경우 http://msdn.microsoft.com/en-us/library/w22x2hw6.aspx에 설명 된대로

public ushort GetBytesFromBlaster(IntPtr dataBytes, int arraySize) 
{ 
    byte[] managed = new byte[arraySize]; 
    Marshal.Copy(dataBytes, managed, 0, arraySize); 
    managed[0] = (byte)'a'; 
    managed[1] = (byte)'b'; 
    managed[2] = (byte)'c'; 
    Marshal.Copy(managed, 0, dataBytes, arraySize); 
    return 3; 
} 

는 또한 사용자 지정 마샬 러를 구현할 수 있습니다 : 예를 들어

http://msdn.microsoft.com/en-us/library/ms146625.aspx
http://msdn.microsoft.com/en-us/library/ms146631.aspx

당신이 필요로하는 것을하는 것이 아닙니다. 그러나 그것은 더 많은 일처럼 보입니다.

public ushort GetBytesFromBlaster(
    [MarshalAs(UnmanagedType.LPArray, SizeConst=3)] 
    byte[] dataBytes 
) 

을 기본 마샬은 당신을 위해 나머지를 수행해야합니다

+0

그건 속임수 였어! 고마워, 제임스! –

0

나는 당신이 단지 SizeConst 속성을 추가 할 필요가 있다고 생각합니다.

관련 문제