Q&A

  • C++ Dll값을받은방법좀..
C++ Dll 소스
<!--CodeS-->
#include <windows.h>
#define DLLFunction  __declspec(dllexport)
extern "C" {
        DLLFunction int sam(int w,int h,unsigned int *uu);
    DLLFunction unsigned int * sam2(int w,int h);
}

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved){
    return TRUE;
}

DLLFunction int sam(int w,int h,unsigned int *uu){
   int i,j,v;
   v=0;
   for(i=0;i<w;i++){
        for(j=0;j<w;j++){
             uu[v]=i*j;
              v++;
        }

    }
    return v;
}

DLLFunction unsigned int * sam2(int w,int h){
    int i,j,v;
    unsigned int *uu;
    uu=new unsigned int[w*h];
    v=0;
    for(i=0;i<w;i++){
         for(j=0;j<w;j++){
            uu[v]=i*j;
            v++;
        }
    }
    return uu;
}
<!--CodeE-->

위에 두함수에 sam unsigned int *uu 값을 받고 싶어서 만들었는데 돌아오는값이 nil이더라구요
그래서 아래 sam2로 리턴값을 받고 싶은데 역시 제대로 된값은 안옴니다.
결론은 C++ dll에 unsigned int *uu 값을 받고 싶은데 어떻게 해야하는지요. 몇일 삽질하다가 올리네요.
가르침부탁드리겠습니다..

아래 델파이 소스...길어서 조금 축약함...
<!--CodeS-->
Type
  _TAyuv=array of integer;
  _PTAyuv=^_TAyuv;

implementation
        function sam(w,h:integer;var yuv : _PTAyuv):integer; cdecl; external 's1.Dll';
        function sam2(w,h:integer):_PTAyuv; cdecl; external 's1.Dll';
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
   PAyuv:_PTAyuv;
   Ayuv:_TAyuv;
   w,h,r,i,j:integer;
begin
   w:=2;
   h:=3;
   new(PAyuv);
   setlength(PAyuv^,100);
   setlength(Ayuv,100);
   r:=sam(w,h,PAyuv);
   Ayuv:= _TAyuv(PAyuv^);
   memo1.Lines.add(IntToStr(Integer(r)));
   memo1.Lines.add(IntToStr(length(Ayuv)));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
   PAyuv:_PTAyuv;
   w,h,r,i,j:integer;
begin
   w:=2;
   h:=3;
   new(PAyuv);
   setlength(Ayuv,100);
   memo1.Lines.add(IntToStr(length(Ayuv)));
   PAyuv:=_PTAyuv(sam2(w,h));
   memo1.Lines.add(IntToStr(length(PAyuv^)));
end;
<!--CodeE-->
2  COMMENTS
  • Profile
    최용일 2009.02.26 20:54
    array of Integer와 같은 동적배열은 델파이만의 고유한 자료형입니다. 다른 언어와 호환되는 타입이 없습니다. 위와 같이 다른 언어로 만들어진 DLL에서는 사용하시면 안됩니다.
    메모리 할당하고 나서 해제하는 코드도 없군요... Dispose로 해제해주셔야...

    형선언을 사용하기에 충분히 큰 배열이나 크기가 0인 배열로 바꾸세요...
    type
    _TAyuv=array[0..65535] of Integer;
    혹은
    type
    _TAyuv=array[0..0] of integer;

    위와 같이 크기가 데이터형과 다르거나 호출할때마다 바뀌는 경우는 New보다는 GetMem을 사용하세요.

    GetMem(PAyuv, SizeOf(Integer) * 100); // SizeOf(Integer) ==> 배열의 element size

    DLL에서 sam함수의 마지막 파라매터가 "unsigned int *uu" 인데 var파라매터에 포인터형으로 되어 있네요... 이렇게 선언하실려면 C에서 unsigned int **uu 로 되어야 할 것입니다.

    sam2같은 함수는 조금 위험한 함수죠... DLL에서 메모리 할당하고 호출하는쪽에서 메모리를 해제를 해야하니까요... 메모리 할당과 해제는 한곳에서 하는것이 좋습니다.
    위 코드에는 메모리 해제에 대한 코딩이 전혀 없군요...
  • Profile
    박래혁 2009.02.26 22:09
    소스를 축약하다보니..빠진부분이 많네요..^^...
    하여튼 가르침 감사합니다...