这是indexloc提供的服务,不要输入任何密码
Skip to content

not support struct type in arguments or return type #3

@windmemory

Description

@windmemory

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions