-
Notifications
You must be signed in to change notification settings - Fork 1
Description
TL;DR:
Currently ffi-adapter supports below data types mapping:
const designTypeMap = new Map<DesignType, FfiType[]>()
.set(undefined, ['void'])
.set(String, ['string'])
.set(Number, [
'int',
'int64',
'uint64',
])
.set(Buffer, ['pointer'])
.set(Boolean, ['bool'])In this mapping, I can not pass a specific type for numbers. Like uint, uint8, int16 etc.
Whole story
I was working on the wxwork archived message project, and they provided .so and .dll file to get the message data from server. And the function definition like below:
typedef struct WeWorkFinanceSdk_t WeWorkFinanceSdk_t;
// 数据
typedef struct Slice_t {
char* buf;
int len;
} Slice_t;
WeWorkFinanceSdk_t* NewSdk();
int Init(WeWorkFinanceSdk_t* sdk, const char* corpid, const char* secret);
int GetChatData(WeWorkFinanceSdk_t* sdk, unsigned long long seq, unsigned int limit, const char *proxy,const char* passwd, int timeout,Slice_t* chatDatas);
Slice_t* NewSlice();
void FreeSlice(Slice_t* slice);
char* GetContentFromSlice(Slice_t* slice);At first I defined my class according to above interfaces like this:
@LIBRARY(libraryPath)
export class WeWorkMessageSDK {
@API('pointer')
NewSdk(): Promise<Buffer> { return RETURN() }
@API('int')
Init(sdk: Buffer, corpid: string, secret: string): Promise<number> { return RETURN(sdk, corpid, secret) }
@API('pointer')
NewSlice(): Promise<Buffer> { return RETURN() }
@API('void')
FreeSlice(slice: Buffer): Promise<void> { return RETURN(slice) }
@API('string')
GetContentFromSlice(slice: Buffer): Promise<string> { return RETURN(slice) }
@API('int')
GetChatData(sdk: Buffer, seq: number, limit: number, proxy: string, passwd: string, timeout: number, chatDatas: Buffer): Promise<number> { return RETURN(sdk, seq, limit, proxy, passwd, timeout, chatDatas) };
}When I ran the GetChatData function call, it always throw a Segmentation Fault. Then I changed to node-ffi with struct type:
const sliceRawStruct = Struct({
buf: ref.refType(ref.types.char),
len: 'int',
});
const slicePtr = ref.refType(sliceRawStruct);
const sdkLibrary = ffi.Library(libraryPath, {
'NewSdk': [ sdkPtr, [] ],
'Init': [ 'int', [ sdkPtr, 'string', 'string' ] ],
'NewSlice': [ slicePtr, [] ],
'FreeSlice': [ 'void', [ slicePtr ] ],
'GetContentFromSlice': [ 'string', [ slicePtr ] ],
'GetChatData': [ 'int', [ sdkPtr, 'uint8', 'uint', 'string', 'string', 'int', slicePtr ] ],
'DestroySdk': [ 'void', [ sdkPtr] ],
});Then the GetChatData works randomly, sometimes it still throw Segmentation Fault, but sometimes it works fine.
I don't know why this happened, and still trying to find a solution, but from my experiment, without the ability to define an accurate number types, I will always get the segmentation fault. I think that is related to the function code stored inside memory, if we can not set the right number type, it will mess up with the memory.