2012-02-16 3 views
1

.net 3.5에서 .net 4.0으로 프로젝트를 마이그레이션 할 때 다음과 같은 문제가 있습니다. 이 같이 DllImport 문이있다 : 두 가지 기능이 잘 작동 .NET 3.5가져온 네이티브 함수가 .NET 4.0에서 작동하지 않습니다.

<DllImport("hid64.dll")> _ 
Public Sub GenerateHardwareID(_ 
     <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal Buffer As Byte(), _ 
     ByVal BufferLength As Int32) 
End Sub 

<DllImport("hid64.dll")> _ 
Public Function BufferToString(_ 
     <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal Buffer As Byte(), _ 
     ByVal BufferLength As Int32) As <MarshalAs(UnmanagedType.LPWStr)> String 
End Function 

은. 그러나 .NET 4.0의 경우 BufferToString 함수를 호출하면 예외가 발생하지 않고 programm 실행이 중단됩니다.
나는 DllImport 속성의 필드 인 CallingConvention, CharSet 등과 같이 놀았습니다. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx 성공하지 못했습니다.

이 변형 :

<DllImport("hid64.dll", CharSet:=CharSet.Auto, PreserveSig:=False, SetLastError:=True)> _ 
Public Function BufferToString(_ 
     <MarshalAs(UnmanagedType.LPArray)> ByVal Buffer As Byte(), _ 
     ByVal BufferLength As Int32) As <MarshalAs(UnmanagedType.LPWStr)> String 
End Function 

이 programm에 실행하지만 함수가 반환 '아무것도'를 중단하지 않습니다.

답변

1

다음은 내가 가장 가능성있는 설명이라고 생각하는 것입니다.

BufferToString 함수의 반환 값은 문자열입니다. p/invoke marshaller는 네이티브에서 관리로 마샬 러해야합니다. 네이티브 코드가 COM 할당 자에 의해 할당 된 Null 종료 문자 포인터를 반환한다고 가정하여이를 수행합니다. .net 문자열로 내용을 전송하면 포인터에 CoTaskMemFree이 호출됩니다. 해당 메모리가 COM 할당 자에 의해 할당되지 않은 경우이 시점에서 실패를 볼 수 있습니다.

문제를 해결하려면 몇 가지 옵션이 있습니다. BufferToString에 대한 p/invoke를 변경하여 IntPtr을 반환 할 수 있습니다. 내용을 Marshal.PtrToStringUni과 함께 .net 문자열로 복사하십시오. 그러면 관리되지 않는 메모리를 삭제할 책임이 있습니다. 아마도 관리되지 않는 라이브러리는이를 수행 할 수있는 메커니즘을 제공합니다.

관리되지 않는 라이브러리를 작성한 경우 대체 솔루션을 사용할 수 있습니다. p/invoke는 그대로 현재의 상태로두고 있지만 CoTaskMemAlloc을 사용하여 반환 값을 할당하도록 관리되지 않는 라이브러리를 변경하십시오. 그러면 p/invoke 마샬 러의 가정과 일치하게됩니다.

+1

David, 명확히 설명해 주셔서 감사합니다. 그것은 문제의 해결책입니다. – KorVet

관련 문제