목요일, 9월 17, 2009

DLL Test in C/C++, Delphi

사용하지 않고 있다가 꼭 사용할 때가 되면 잊어 버린다.
잊어 버릴까봐 일단 급하게 적어 둔다... -_-;;; 쳇..!

//
// Project:
// Purpose: DLL test
// Author: HoJung Kim (godmode2k@hotmail.com)
// Date: September 17, 2009
// NOTE:
//



//
// Linux ================================================================
//
// [In C/C++]
// ----------------------------------------------------------------------
//! Export
// ----------------------------------------------------------------------
extern "C" int __FUNCTION__(int, float, float, int, float, char*);
extern "C" int __FUNCTION__(int a1, float a2, float a3, int a4, float a5, char* a6) {
...
}
// Build
GCC_BIN=/usr/bin/gcc
INC_LIB_SO_FLAGS="-DLINUX"
INC_SO="-fPIC -shared -Wl,-soname,$LIB_OUTPUT_SO_NAME -o $LIB_WORK_DIR$LIB_OUTPUT_SO *.o"
$GCC_BIN $INC_LIB_SO_FLAGS $INC_SO
// ----------------------------------------------------------------------
//! Dynamic Linking
// ----------------------------------------------------------------------
#ifdef __LINUX__
# include
#else
/* __WIN32__ || _WIN32 || WIN32 */
# include
#endif
#ifdef __LINUX__
//# define dl_load(a) dlopen(a, RTLD_NOWIRTLD_GLOBAL)
# define dl_load(a) dlopen(a, RTLD_NOW)
# define dl_close(a) dlclose(a)
# define dl_sym(a, str) dlsym(a, str)
# define dl_error dlerror
typedef void* g_pFnc;
typedef g_pFnc g_pHandle;
#else
/* __WIN32__ || _WIN32 || WIN32 */
# define dl_load(a) LoadLibrary(a)
# define dl_close(a) FreeLibrary(a)
# define dl_sym(a, str) GetProcAddress(a, str)
#endif
typedef int (*gFp)(int, float, float, int, float, char*)
#endif
//
int main(int argc, char** argv) {
#ifdef __LINUX__
g_pHandle dlFile = VM_null;
//dlFile = dl_load( "test.so" );
dlFile = dl_load( "./test.so" );
#else
/* __WIN32__ || _WIN32 || WIN32 */
g_pHandle dlFile = 0;
dlFile = dl_load( "test.dll" );
#endif

if( !dlFile ) {
#ifdef __LINUX__
fprintf( stderr, "Error: Library load: %s\n", dl_error() );
#else
/* __WIN32__ || _WIN32 || WIN32 */
fprintf( stderr, "Error: Library load: %d\n", GetLastError() );
#endif

return -1;
}

gFp fnXXXXX = (gFp)dl_sym( dlFile, "XXXXX" );

if( !fnXXXXX ) {
#if __LINUX__
fprintf( stderr, "Error: Library link: %p\n", vmCC );
#else
/* __WIN32__ || _WIN32 || WIN32 */
fprintf( stderr, "Error: Library link: %d\n", GetLastError() );
#endif

return -1;
}

fprintf( stdout, "Test\n" );

if( argc < 2 ) {
return -1;
}

fnXXXXX( ..... );
dl_close( dlFile );

return 0;
}



//
// WIN32 ================================================================
//
// [In C/C++]
// ----------------------------------------------------------------------
//! Export
// ----------------------------------------------------------------------
extern "C" __declspec(dllexport) int __FUNCTION__(int, float, float, int, float, char*);
extern "C" __declspec(dllexport) int __FUNCTION__(int a1, float a2, float a3, int a4, float a5, char* a6) {
...
}
// ----------------------------------------------------------------------
//! Dynamic Linking
// ----------------------------------------------------------------------
#include "windows.h" // '<>' Angle Brackets Character 작성 안됨
...
//#pragma comment( lib, "./test.lib" )
typedef bool (*gFP)(int, float, float, int, float, char*);
int myFunc(void);
int main(void) {
int ret = 0;
ret = myFunc();
return ret;
}
int myFunc(void) {
bool ret = false;
HINSTANCE hInst;

hInst = LoadLibrary( "test.dll" );

if( !hInst ) {
fprintf( stderr, "[LOG] Cannot open test.dll\n" );
return 1;
}

gFP gfp = (gFP)GetProcAddress( hInst, "XXXXX" );
ret = gfp( 0, 1.0f, 1.0f, 0, 1.0f, "AAAAA" );

if( ret )
fprintf( stdout, "[LOG] Generated. [OK]\n" );
else
fprintf( stderr, "[LOG] Generated. [FAIL]\n" );

FreeLibrary( hInst );

return (ret ? true : false);
}
// ----------------------------------------------------------------------


// [In Delphi]
// ----------------------------------------------------------------------
//! Export
// ----------------------------------------------------------------------
library test;
uses
{ ---------------------------------------------- }
{ Component }
{ ---------------------------------------------- }
Windows, { define at the first! }
SysUtils, { use so many inline function like DeleteFile for Windows.DeleteFile }
Classes, { TMemorySTream, ... }
{ Someday we need to these }
StdVcl,
Messages,
Controls,
{ }
StrUtils,
ShellApi,
Dialogs,
{ Network }
HttpApp,
IdTCPConnection,
IdTCPClient,
IdHTTP,
IdMultipartFormData
{ ---------------------------------------------- }
;

{$R *.res}

type
{}

var
{}

function XXXXX(a1: integer; a2, a3: single; a4: integer; a5: single; a6: PChar) : integer; stdcall; export;
begin
end;

//! Exports
exports
XXXXX
;

//! End
begin
end.
// ----------------------------------------------------------------------
//! Static Linking
// ----------------------------------------------------------------------
unit MyUnit1;
interface
uses Windows;
procedure gfp(a1: integer; a2, a3: single; a4: integer = 0; a5: single = 0; a6: PChar = nil ); stdcall; external 'test.dll';
// ----------------------------------------------------------------------
//! Dynamic Linking
// ----------------------------------------------------------------------
unit MyUnit1;
interface
uses Windows;
type
TDllFunc = function (a1: integer; a2, a3: single; a4: integer; a5: single; a6: PChar) : HResult; cdecl;
var
g_iDllHandle: integer;

function gfp: integer;
var
ret: integer;
DllFunc: TDllFunc;
begin
ret := 0; // false
try
g_iDllHandle := 0;
g_iDllHandle := LoadLibrary( '.\test.dll' );
if( g_iDllHandle = 0 ) then begin
ShowMessage( '[ERROR] Cannot find ./test.dll' );
ret := 0; // false
end
else begin
@DllFunc := GetProcAddress( g_iDllHandle, 'XXXXX' );

if( @DllFunc = nil ) then begin
ShowMessage( '[ERROR] Cannot get process address' );
ret := 0; // false
end
else begin
ret := DllFunc( 0, 1.0f, 1.0f, 0, 1.0f, PChar('AAAAA') );
end;
end;
finally
FreeLibrary( g_iDllHandle );
g_iDllHandle := 0;
DllFunc := nil;
end; // try ~ finally

result := ret;
end;
// ----------------------------------------------------------------------

댓글 없음:

댓글 쓰기