2009-11-25 10 views
0

DLL이 있고 그것을 델파이델파이 DLL 호출

에서 호출하고 싶습니다.
extern "C" export_dll_function int RetScreen(int number, char** pbuffer, unsigned long* psize, 
IMAGE_RESOLUTION resolution, float zoom, int dx, int dy); 


[DllImport("API.DLL", EntryPoint = "_RetScreen")] 
public static extern int pRetScreen(int number, ref byte[] pdata, ref long size, int res, float zoom, int dx, int dy); 

델파이 타입이 char ** pbuffer를 프로토 타입이라고합니다. (그것은 이미지이다)

답변

1

Jqno 씨가 닫습니다. char **는 C- 문자열의 배열이지만 C는 델파이처럼 배열이나 문자열을 처리하지 않습니다. 여기에 기본 유형은 PAnsiChar이고 무한 배열이 필요합니다. 다음과 같이 정의 PCStringArray,로 선언 :

type 
    TCStringArray = Array [0..0] of PAnsiChar; 
    PCStringArray = ^TCStringArray; 

번호가 가장 가능성이 배열에 상한의 수입니다. [0..0]으로 지정하지만 실제 크기는 [0..number - 1]입니다.

+2

마이너 질의 :'char **'는 C 문자열의 배열이 아니며'char *'에 대한 포인터입니다.다음 메모리 위치에 더 많은 포인터가있을 수 있습니다 (따라서 배열을 형성합니다). 그러나 선언에서 알 수 없습니다. – mghie

+2

이미지가 있으면 'Byte'가 C# 선언에 반영된대로 거의 확실한 선택입니다. C++ 코드는'unsigned char'을 사용해야합니다. –

2

C 버전뿐만 아니라 C# 정의에서 내 단서를 살펴보면 pbuffer가 바이트 버퍼를 가리키는 포인터 인 것처럼 보입니다. 델파이에서는 참조로 전달 된 PByte가 더 좋을 것입니다. PByte를 원할 때 PChar를 사용할 필요가 없습니다.

예 :

을 -
type  
    IMAGE_RESOLUTION = integer; // judging from the c# parameters... 
    float = Single; // 4 bytes... 

    TRetScreenFn = function(number: integer; 
          var buffer: PByte; 
          var size: Cardinal; 
          resolution: IMAGE_RESOLUTION; 
          zoom: float; 
          dx : integer; 
          dy : integer): integer; cdecl; 

(이것은이 아니라면, 아마 stdcall을 대신 할 것 "export_dll_function"가 무엇을 의미하는지에 따라, 여기 잘못 될 수 있습니다. 나는 cdecl을 여기에 통근 "C"에서 있으리라 믿고있어.)

버퍼 또는 크기 대신에 nil이 주어지면 "var"를 사용할 수 없습니다. 이 경우 다음과 같이해야합니다.

type 
    PPByte = ^PByte; 
    PCardinal = ^Cardinal; 

    TRetScreenFn = function(number: integer; 
          buffer: PPByte; 
          size: PCardinal; 
          resolution: IMAGE_RESOLUTION; 
          zoom: float; 
          dx : integer; 
          dy : integer): integer; cdecl; 

이것은 본질적으로 같은 것입니다. 첫 번째 버전을 제외하고 컴파일러는 var 매개 변수를 non-nil로 지정합니다. 이 두 번째 버전은 포인터 만보고 상관하지 않습니다. 그것은 작동

var 
    retScreen : TRetScreenFn; 
    dll : HMODULE; 
begin 
    dll := LoadLibrary("API.dll"); 
    try 
    retScreen := TRetScreenFn(GetProcAddress(dll, "RetScreen")); 

    // ... call retScreen(); do stuff... 
    finally 
    CloseHandle(dll); 
    end; 
end; 
+0

'buffer' 매개 변수의 의미에 동의합니다, +1. 하지만 아마도 "큐"가 아니라 "큐"를 의미할까요? – mghie

+0

가능성이 없습니다. char **는 거의 항상 "char *에 대한 포인터"가 아니라 char *의 배열을 의미합니다. 이것이 이미지의 경우, 각 개별의 char *는 1 개의 주사선 (수평 픽셀 행)을 나타내, 각 새로운 주사선은 메모리 정렬이나 그와 유사한 이유 때문에, 마지막 주사선이 끝난 직후에 반드시 시작할 필요는 없다. –

+2

Mason,'char **'는 "호출 된 함수에 의해 할당되고 호출자에게 반환되는 간단한 char 버퍼"를 의미합니다. C# 선언은 특히 그 점에 관해 말하고 있습니다. –

0

:

는 그런 다음 나머지 (제정신 오류 검사를 무시)를 알고있다! Otherchirps, Rob Kennedy, mghie, Mason Wheeler, 대단히 감사합니다! (otherchirps의 게시물을 참조)이 올바른 함수 선언입니다 :

 
TRetScreenFn = function(number: integer; 
          var buffer: PByte; 
          var size: Cardinal; 
          resolution: IMAGE_RESOLUTION; 
          zoom: float; 
          dx : integer; 
          dy : integer): integer; stdcall; 

(stdcall을 함께 일)이 매개 변수와 함께 호출

 
type 
    PByte = ^TByte; 
    TByte = array of byte; 

: 다른 사람 같은 문제가 들어

RetScreen (int, buffer : PByte, int, int, float, int, int) 해당 매개 변수를 기반으로 이미지를 가져 오는 DLL 내부 함수 이름은 GetImage 및 GetWindowImageQEx입니다.

롭 케네디, 내가 갖고 있지 않기 때문에 더 많은 문서를 게시 할 수 없습니다. Arecont의 카메라 DLL (AV2000sdk.dll)입니다. 안타깝게도 Arecont는 델파이와 닷넷을위한 전체 SDK를 다운로드하는 것을 허용하지 않습니다.

다시 한번 감사드립니다.

+0

죄송합니다 - PByte를 재정의하는 이유가 확실하지 않습니다. "내장"유형 중 하나로 이미 정의되어 있어야합니다. 그것은 다음과 같습니다 : 타입 PByte =^Byte; 바이트 = 0..255; 명시 적으로 배열 유형으로 지정하는 이유가 있습니까? – otherchirps

+0

실제로, PByte를 다시 정의하는 다른 이유는 없습니다. 단, 여기와 c/p를 읽는 것이 더 명확해야합니다. – benjamin