p/invoke 코드와 Delphi 코드가 일치하지 않습니다. Delphi 코드는 표시하지 않았지만 C# 코드는 Delphi 코드의 모양을 알기에 충분합니다.
DllImport
속성은 호출 규칙 및 문자 집합에 기본값을 사용합니다. 즉, 호출 규칙은 stdcall
이고 문자 집합은 ANSI입니다. 마샬링 특성을 지정하지 않았으므로 기본 마샬링을 사용해야합니다.
function MyMethod(someStringParam: PChar): PChar; stdcall;
begin
Result := ??;
end;
을 그리고 지금 여기에 문제는 다음과 같습니다
따라서 델파이 코드는 다음과 같이해야합니다. p/invoke marshaller는 매우 특별한 방법으로 string
반환 값을 처리합니다. 반환 값의 메모리를 할당 해제하는 것은 p/invoke marshaller의 책임이라고 가정합니다. 그리고 네이티브 코드와 동일한 할당자를 사용해야합니다. 마샬 러가 가정하는 것은 공유 COM 할당자가 사용된다는 것입니다.
그래서 기본 코드는 CoTaskMemAlloc
을 호출하여 COM 할당자를 통해 메모리를 할당해야한다는 규칙이 있습니다. 내 코드는 당신의 코드가 그렇게하지 않는다는 것이고 그것은 확실히 오류를 가져올 것입니다.
다음은 코드에서 C# 서명과 함께 작동하는 원시 델파이 함수를 만드는 방법의 예입니다. 이 방법을 채택 할 수있는 동안
function MyMethod(someStringParam: PChar): PChar; stdcall;
var
Size: Integer;
begin
Size := SizeOf(Char)*(StrLen(someStringParam)+1);//+1 for zero-terminator
Result := CoTaskMemAlloc(Size);
Move(someStringParam^, Result^, Size);
end;
나는 대안을 권장합니다. 모든 문자열을 C# 측의
BSTR
및 델파이 측의
WideString
으로 마샬링하십시오. COM 할당 자에 의해 할당되는 일치하는 형식입니다. 양 당사자는 이러한 유형으로 무엇을해야하는지 정확히 알고 있으며 인생을 더 쉽게 만듭니다.
델파이는 함수 반환 값으로 다른 ABI를 사용하기 때문에 안타깝게도 interop 경계를 가로 질러 델파이 함수에서 WideString
을 반환 할 수 없습니다. 이 문제에 대한 자세한 내용은 내 질문에 있습니다. Why can a WideString not be used as a function return value for interop?
따라서이 문제를 해결하기 위해 델파이 코드의 반환 형식을 TBStr
으로 선언 할 수 있습니다.귀하의 코드는 다음과 같을 것이다 : 나를 위해
C#을
[DllImport(@"MyDll.dll")]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string MyMethod(
[MarshalAs(UnmanagedType.BStr)]
string someStringParam
);
델파이
function MyMethod(someStringParam: WideString): TBStr; stdcall;
begin
Result := SysAllocString(POleStr(someStringParam));
end;
DLL의 함수 호출 규칙은 무엇입니까? – ain
델파이 메소드의 코드를 보여주세요 –
델파이에서 함수의 큰 확률 선언은 C#의 카운터와 다르다 –