꾸~벅~! 안녕하세요~! 칭구가 C Code (Visual C++ Compile)로 만든 Dll 화일을 Delphi에서 사용하려고 합니다. dll 내의 C code function을 Delphi에서 어떻게 사용해야할지 몰라서 이렇게 글을 올립니다. 게시판을 뒤져보니, 비슷한 질문...
홍동선
•
2000.04.28 23:20
최용일님 감사합니다.
글구, 추가로 제가 찾은 자료를 올립니다.
=================================...
홍동선
•
2000.04.28 23:20
최용일님 감사합니다.
글구, 추가로 제가 찾은 자료를 올립니다.
=================================...
최용일
•
2000.04.29 00:22
안녕하세요. 최용일입니다.
함수 호출규약에 대해서 여러가지로 잘못알고 계시네요.
> cdecl 방식이 ...
최용일
•
2000.04.27 19:53
안녕하세요. 최용일입니다.
interface
procedure Dll_Proc(parameters...); stdcall;
function Dll_...
글구, 추가로 제가 찾은 자료를 올립니다.
========================================
제 목:[답변] VC++ DLL을 델파이에서 쓰기/반대로
보낸이:김정
안녕하세요
고드름 김정입니다.
아래에 작성하는 내용은 제가 작업해서 쓰는 방법입니다.
따라서 가장 최선의 방법이라고는 할 수 없습니다.
그점을 양해해주시기 바랍니다.
***
1. VC++ 작업한 DLL을 델파이에서 사용하기
우선 함수 파라미터를 잘 확인하셔야 합니다.
이것이 뭣이냐 하면,
델파이(파스칼계열)이나 C 계열은 함수를 호출할 때 파라미터를
스택에 넣고 빼는 순서가 다르거든요..
다음은 그 구분입니다.
Directive Parameter order Clean-up register 사용 여부
-------------------------------------------------------------------------------
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
(*델파이5 헬프에서 발췌. 어느 버전이든 똑같음*)
위에 보시면 cdecl 방식이 있습니다.
cdecl 방식이 C/C++에서 사용되는 함수 호출 방식의 표준입니다.
물론 함수를 선언할 때 다음과 같이 표시합니다.
procedure testproc( param1 : integer; param2 : pchar ); cdecl;
프로시저가 아니라 함수일 경우는,
function testfunc( param1 : integer; param2 : pchar ) : integer; stdcall;
보통은 DLL로 export하는 쪽에서 사용하는 쪽의 방식을 맞춥니다.
API함수들의 경우는 PASCAL 타입을 많이 쓰고,
델파이나 C-Builder의 경우는 stdcall 또는 safecall을 쓰는 것을 아시죠??
따라서 VC++에서 그냥 export하셨다면,
델파이 쪽에서 선언하는 부분에 cdecl 방식을 넣어주세요...
함수명은 C/C++에서 사용하신 그대로 쓰세요.(대소문자 구분해서요.)
함수명을 정확하게 쓰지 않는 경우 링크에러가 날수 있습니다.
그리고, 주의 하실 부분이 있습니다.
바로 스트링을 넘기는 부분이지요. 위에 함수 선언처럼 PCHAR로 받으면
되지만, 가끔은 문제가 되는 경우도 있더군요.
레퍼런스 참조때문인 것 같은데, 그런 경우에 포인터를 하나 더 달아주시면
해결하실 수 있습니다.
제 경우에는 델파이에서 함수 포인터를 넘겨주고,
콜백함수로 버퍼의 포인터가 넘어오는데,
이것을 PCHAR로 받아서 쓰면 Access Violation이 나더군요,
그래서 PPCHAR = ^PCHAR 를 선언해서 PPCHAR로 받아서, buf^로 사용했습니다.
(*결론*)
*** VC++에서 선언하기 (Export)
extern "C" __declspec(dllexport) int __cdecl btInputText(char *buf, int ch)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return(InputText(buf, ch));
}
*** DELPHI에서 선언하기 (Import)
interface
procedure btInputText( Buf : PChar; ch : integer ); cdecl;
implementation
procedure btInputTex; external 'test.dll'; cdecl;
위와 같이 하시면 됩니다.
그리고 동적링크도 있겠죠. LoadLibrary를 사용하는 방법인데,
어차피 위처럼 선언해도 동적인거 아닌가 싶기도하고.. ^^
일반 델파이 서적에 더 자세히 나와있을겁니다. 참고하시고요,
2. 델파이로 만는 DLL을 VC++에서 사용하기
뭐 위와 반대니까 별로 차이는 없습니다.
다만 VC++의 경우 링크 상의 문제로 인하여,
LIB파일이 있던가, 아니면 LoadLibrary를 사용하셔야 합니다.
델파이에서 DLL을 만들면 LIB가 생기지 않는 관계로,
(제 생각입니다. 어찌하면 생기는 줄도.. 그런가??)
저는 주로 LoadLibrary를 사용합니다.
그 과정은 다음과 같습니다.
(델파이로 DLL만드는 과정은 생략! 다만 cdecl 빼먹지 마세요~)
(1). 함수 포인터 선언하기
typedef int (__cdecl *Pgetgroup)(char* PID,
char* PIDpwd,
int GroupNum,
char* MailAddr);
Pgetgroup getgroup;
(2). DLL 부르기
(MFC의 경우라면 OnInitDialog() 내에 선언하곤 합니다.아시죠?)
theDLL = LoadLibrary("test.dll");
getgroup = (Pgetgroup)GetProcAddress((HMODULE)theDLL, "getgroup");
(3). 함수 사용
char PID[30] = {"godrm"};
char PIDpwd[10] = {"1234"};
char GroupAddr[512] = {""};
int GroupNum = 1;
if (getgroup( PID, PIDpwd, GroupNum, GroupAddr )<0)
{
MessageBox( "Fail" );
}
이상입니다.
온라인 상에서 대충 붙여넣고 했더니만,
정리가 어떻게 됐는지 모르겠네요.
참고가 되시길 바랍니다.
이 글을 보시고도 정리가 안 되시면, 다시 질문하세요. 자세하게~
메일을 보내셔도 시간되는데로(?) 답변해드리겠습니다.
즐팅되세요..그람..
제 목:[참고] VC++ DLL 사용에 관하여
보낸이:김정
안녕하세요..
고드름 김정입니다.
아래 답변 드렸던 내용 중에서
정정해 드릴 부분이 있더군요.. ^^
찾아보니, WIN32 표준 호출 방식이 stdcall 이구요,
델파이는 fastcall 이 디폴트더군요..
참고하세요.. 그람~~