( pass struct to char pointer(char*) in DLL export function )
DLL: int testFunc(int a, int* b = 0, char* _items = 0);
exe: struct 변수를 memcpy 로 char type 의 buffer 에 넣어서 buffer address 를 char* 에 넘긴다.
아래는 test code 다.
꼭 사용할 때면 새로 작성을 해서 테스트를 하다보니 여기에 그냥 적어 놓는다. 에휴...
참고로, Delphi 에서 struct 를 char* 로 전달 할 때는 다음과 같이 하자.
int* 는 Pointer( @_array_var_[0] {trick} );
char* 거나 struct 를 char* 로 전달할 때는 PChar(@_struct_var); 이렇게 사용하자.
--- Delphi ---
type
TSubItem = packed record
str: string;
a: integer;
end;
TItems = packed record
flag: boolean;
item1: TSubItem;
item2: TSubItem;
end;
TDllFunc_ = function (...; intArray: Pointer; pStr: PChar;...): HResult; cdecl;
TIntArray = array[0..3] of integer;
var
g_Items: TItems;
g_IntArray: TIntArray;
implementation
//{$R *.dfm}
procedure aaa;
var
...
DllFunc: TDllFunc_;
begin
...
g_IntArray[0] := 1;
g_IntArray[1] := 2;
g_IntArray[2] := 3;
DllFunc( ..., Pointer(@g_IntArray[0]{trick}), PChar(@g_Items), ... );
end;
//
// C/C++
//
--- DLL: test.c ---
#include "windows.h"
#include "iostream"
#define EXTC_API extern "C"
#define CLIB_API /*extern "C"*/ __declspec(dllexport)
extern "C" {
#pragma pack(push)
#pragma pack(1)
typedef struct {
char* pStr;
int a;
int b;
} item_st;
typedef struct {
boolean enableItem1;
boolean enableItem2;
boolean enableItem3;
item_st item1;
item_st item2;
item_st item3;
} items_st;
#pragma pack(pop)
}
EXTC_API CLIB_API int testFunc(int a, int* b = 0, char* _items = 0);
/*static*/ items_st* items = NULL;
EXTC_API CLIB_API int testFunc(int a, int* b, char* _items) {
items = (items_st*)_items; // 'items': Global STATIC variable
for( int i = 0; i < 3; i++ ) fprintf( fp, "[%d] = %d\n", i, *(b+i) ); fprintf( stdout, "%d, %d, %d\n", items->enableItem1, items->enableItem2, items->enableItem3 );
fprintf( stdout, "%s, %d, %d\n", items->item1.pStr, items->item1.a, items->item1.b );
fprintf( stdout, "%s, %d, %d\n", items->item2.pStr, items->item2.a, items->item2.b );
fprintf( stdout, "%s, %d, %d\n", items->item3.pStr, items->item3.a, items->item3.b );
return 0;
}
--- EXE: test_bin.c ---
#include "windows.h"
#include "iostream"
#pragma pack(push)
#pragma pack(1)
typedef struct {
char* pStr;
int a;
int b;
} item_st;
typedef struct {
boolean enableItem1;
boolean enableItem2;
boolean enableItem3;
item_st item1;
item_st item2;
item_st item3;
} items_st;
#pragma pack(pop)
typedef int (*gFP)(int, int*, char*);
int myFunc(void);
int main(void) {
int ret = 0;
ret = myFunc();
return ret;
}
int myFunc(void) {
int ret = 0;
HINSTANCE hInst;
hInst = LoadLibrary("test.dll");
if( !hInst ) {
fprintf( stderr, "[ERROR] Cannot open test.dll\n" );
return 1;
}
gFP gfp = (gFP)GetProcAddress( hInst, "testFunc" );
{
int bufInt[3] = { 0, 1, 2 };
char bufStrItems[sizeof(items_st)] = { 0 };
items_st items = { 0 };
items.enableItem1 = TRUE;
items.enableItem2 = TRUE;
items.enableItem3 = TRUE;
items.item1.pStr = "AAAAABBBBB";
items.item1.a = 10;
items.item1.b = 10;
items.item2.pStr = "CCCCCDDDDD";
items.item2.a = 20;
items.item2.b = 20;
items.item3.pStr = "EEEEEFFFFF";
items.item3.a = 30;
items.item3.b = 30;
memcpy( bufStrItems, &items, sizeof(items_st) );
ret = gfp( 0, (int*)&bufInt, bufStrItems );
}
if( ret )
fprintf( stdout, "Success\n" );
else
fprintf( stderr, "Fail\n" );
FreeLibrary( hInst );
return (ret ? true : false);
}
-----
Cheers,
June
댓글 없음:
댓글 쓰기