2011-02-23 2 views
4

나는 델파이의 절차가 : 내가 전달Pchar Delphi DLL을 C#으로 가져 오시겠습니까?

procedure PasswordDLL(month integer; password pchar); 
export; 

절차를 출력합니다 암호를 "암호"를 PChar를 .. 내가 읽는 google..and 무슨 .... 심판에서 : HERE 내가 전화 할 때 다음

[DllImport(
    "DelphiPassword.dll", 
    CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi, 
EntryPoint = "PasswordDLL")] 
public static extern void PasswordDLL( 
    int month, 
    [MarshalAs(UnmanagedType.LPStr)] string password 
    ); 

: 및 HERE

내가 가지고 올

string pass = ""; 
PasswordDLL(2, pass); 

"암호"문자열로 출력 할 암호.

하지만 BadImageFormatException 처리되지 않은 얻을 것이다 : 잘못된 형식으로 프로그램을로드하려고했습니다. (HRESULT 예외 : 0x8007000B)

사용 된 함수 형식이 잘못 되었습니까? 내가 PChar에 대해 잘못된 UnmanagedType을 사용했는지는 모르겠지만 읽음에서 LPWStr과 LPStr 중 하나입니다. 뭔가 놓쳤습니까? 사전에

감사합니다 ... 오프

답변

2

먼저 언급하지 않았으므로 이는 델파이 버전 당신의 나는 잘 알고 나보다 다른 이유 델파이 6 가정 응답 할 것이다 사용.

귀하의 델파이 절차는 선언에 호출 규칙을 지정하지 않으므로 가져 오기에 따라 stdcall을 사용하지 않을 것입니다. 스택의 첫 번째 매개 변수를 레지스터에 배치하는 기본 델파이 레지스터 규칙을 사용합니다. Delhpi DLL을 변경할 수 있다면 stdcall을 추가하십시오.을 선언하고 다시 작성한 후 호출 규칙이 일치합니다.

아래 표는 호출 규칙을 요약 한 것입니다. 닷넷 문서를 보면

Directive Parameter order Clean-up Passes parameters in registers? 
--------- --------------- -------- ------------------------------- 
register Left-to-right Routine Yes 
pascal Left-to-right Routine No 
cdecl  Right-to-left Caller No 
stdcall Right-to-left Routine No 
safecall Right-to-left Routine No 

델파이의 레지스터 대회 ( 아래 표 참조)과 일치하는 호출 규칙이있을 것 같지 않습니다 그래서 유일한 옵션은에서 규칙을 변경하는 것 같아요 델파이 DLL을.

Member name Description 
----------- ------------------------ 
Cdecl   The caller cleans the stack. This enables calling functions with varargs, which makes it appropriate to use for methods that accept a variable number of parameters, such as Printf. 
FastCall  This calling convention is not supported. 
StdCall  The callee cleans the stack. This is the default convention for calling unmanaged functions with platform invoke. 
ThisCall  The first parameter is the this pointer and is stored in register ECX. Other parameters are pushed on the stack. This calling convention is used to call methods on classes exported from an unmanaged DLL. 
Winapi  Supported by the .NET Compact Framework. This member is not actually a calling convention, but instead uses the default platform calling convention. For example, on Windows the default is StdCall and on Windows CE .NET it is Cdecl. 

델파이 (6) Pchar (null로 끝나는 ANSI 문자열에 대한 포인터) 마샬링이 올바른 것처럼 보입니다.

+1

감사합니다. 요약하면 나를 이해하는 데 도움이됩니다. :) – King

+1

뭔가 잘못 될 것입니다 : PChar가 가리키는 버퍼는 호출자에 의해 할당되어야합니다. 그렇지 않으면 종료시 AV가 발생합니다 (기껏해야). dll에 전달 된 버퍼의 크기를 지정하는 매개 변수를 추가해야하며, null 문자를 포함하여 데이터를 반환하기에 충분히 큰지 확인하고, 그렇지 않으면 오류를 반환해야합니다. – Stephane

+0

훌륭해.이게 내가 델파이 5와 C#을 완벽하게 조사하고있는 문제를 해결했다. 많은 것을 알고 피트 – nrjohnstone