2014-01-25 5 views
4

У меня есть dll для Delphi, для которого требуется входная строка json (pAnsiChar) и возвращает int как успех или сбой. Мне удалось подключиться к dll из nodejs, используя node-ffi. Тем не менее, я получаю return int value указывает на недопустимую строку json.Вызов функции Delphi stdcall с помощью pAnisChar из узла js

Может кто-то мне точку в направлении того, как вызвать DLL Delphi с PAnsiChar в качестве аргументов функции от узла

Благодаря

+0

Как насчет конвенции? Мои исследования показывают, что для узла ffi требуется cdecl. Знаете ли вы другое? –

+0

Эта DLL использует stdcall, и я могу подключиться к ней с других языков, таких как vba и т. Д. И теперь я могу подключиться к DLL через вызовы node-ffi, возвращая значение для некоторых функций и не смог сделать это на функции, которая принимает json string как PAnsiChar param и возвращает строку json переданному указателю PAnsiChar – user3234437

+0

Я понимаю, что DLL экспортирует функции 'stdcall'. Я убежден, что node-ffi может вызывать только функции 'cdecl'. Вы приняли ответ Реми, который заставляет меня поверить, что у вас есть дополнительная информация об узле-ffi, которая сообщает вам, что node-ffi может фактически называть функции 'stdcall'.Я полагаю, что правдоподобно, что node-ffi может добавить дополнительный код для определения того, подбирал ли вызываемый стек стек и соответствующим образом адаптировал его. Какая у вас информация? –

ответ

4

PAnsiChar в Delphi в C/C++ char*. В заявлении FFI для функции DLL просто объявите параметр PAnsiChar как "string", который является символом char * в FFI с нулевым завершением.

Например, если эта функция Delphi:

function ProcessJson(Json: PAnsiChar): Integer; stdcall; 

node.js код будет выглядеть примерно так:

var ffi = require('ffi'); 

var mydll = ffi.Library('mydll', { 
    'ProcessJson': [ 'int', [ 'string' ] ] 
}); 

var ret = mydll.ProcessJson("json content here"); 
5

Насколько я могу сказать, Node FFI в настоящее время не позволяют вы можете управлять конвенцией о вызовах. И по умолчанию cdecl. Так что на стороне Delphi это выглядит следующим образом:

function MyFunction(str: PAnsiChar): Integer; cdecl; 

На стороне узла FFI я думаю, это выглядит следующим образом:

var ffi = require('ffi'); 
var mylib = ffi.Library('libname', { 
    'MyFunction': [ 'int', [ 'string' ] ] 
}); 
var retval = mylib.MyFunction("some string"); 

Если вы не можете изменить устаревшую DLL, то я боюсь, что вам может потребоваться обернуть его в DLL, которая ничего не делает кроме экспортных функций cdecl, а затем передаст их в функции stdcall унаследованных DLL.

0

Я смотрю в это сам, и на основе исследований, я сделал узел-FFI может обрабатывать следующие соглашения о вызовах:

thiscall, азЬсаИ и MSVC Cdecl на Windows,

По changelog in the readme.

Это не лучший источник информации, но нет упоминания о stdcall в readme. fastcall поддерживается, хотя это также соглашение о вызове очистки вызываемого абонента, поэтому лучше всего переключить свои функции на fastcall вместо cdecl, если вы хотите вызвать DLL Delphi с узлом-ffi.

Я попробую назвать некоторые простые функции StdCall через node-ffi, чтобы проверить, может ли он правильно обработать их и проверить здесь, как только у меня появятся некоторые результаты.

+0

Обновление: у меня был большой успех, используя соглашение о вызове cdecl. См. [Мой проект DLL] (https://github.com/matortheeternal/xedit-lib) и [мои привязки узла-ffi] (https://github.com/matortheetern/shampoo/blob/master/src/xelib. JS). – Mator

Смежные вопросы