【问题标题】:Converting C functions in Delphi 10 Seattle在 Delphi 10 Seattle 中转换 C 函数
【发布时间】:2016-03-23 17:52:22
【问题描述】:

我正在尝试将 API SendAnywhere header file 从 C 转换为适用于 Windows 的 Delphi 10 代码。

使用presented table of Embarcadero我成功转换了一些函数:

typedef void* PaprikaTask;
typedef void* PaprikaAuthToken;

__declspec(dllexport) void paprika_set_apikey(const char* key);
__declspec(dllexport) PaprikaAuthToken paprika_auth_create();
__declspec(dllexport) PaprikaAuthToken paprika_auth_create_with_deviceid(const char* id, const char* password);
__declspec(dllexport) void paprika_auth_close(PaprikaAuthToken auth);
__declspec(dllexport) bool paprika_is_running(PaprikaTask task);
__declspec(dllexport) PaprikaTask paprika_create_download(const wchar_t* key, const wchar_t* destDirPath);
__declspec(dllexport) void paprika_start(PaprikaTask task);

这是我的转换:

PaprikaAuthToken = Pointer;
PaprikaTask = Pointer;

procedure paprika_set_apikey(const key: PChar); cdecl; external 'sendanywhere.dll';
function paprika_auth_create: PaprikaAuthToken; cdecl; external 'sendanywhere.dll';
function paprika_auth_create_with_deviceid(const id: PAnsiChar; const password: PAnsiChar): PaprikaAuthToken; cdecl; external 'sendanywhere.dll';
procedure paprika_auth_close(auth: PaprikaAuthToken); cdecl; external 'sendanywhere.dll';
function paprika_is_running(task: PaprikaTask): Boolean; cdecl; external 'sendanywhere.dll';
function paprika_create_download(const key: PWideChar; const destDirPath: PWideChar): PaprikaTask; cdecl; external 'sendanywhere.dll';
procedure paprika_start(task: PaprikaTask); cdecl; external 'sendanywhere.dll';

SendAnywhere 的示例使用这些函数如下:

PaprikaTask pTask;
PaprikaAuthToken gToken;

paprika_set_apikey("YOUR_API_KEY");
gToken = paprika_auth_create();
pTask = paprika_create_download(L"KEY", L"/tmp"); 
paprika_set_auth(pTask, gToken);
paprika_start(pTask);

这就是我解释正确代码的方式:

var
FAuthToken: PaprikaAuthToken;
FOption: PaprikaOption;   

paprika_set_apikey(PChar('my_correct_api_key'));
FAuthToken = paprika_auth_create();
// backslash for windows
FTask := paprika_create_download(PWideChar('correct_key'), PWideChar('\tmp')); //directory exists
paprika_set_auth(FTask, FAuthToken);
paprika_start(FTask);

我通过函数paprika_is_running检查了任务的工作。它在调用 paprika_start_function 之前返回 FALSE。它在调用 paprika_start_function 后开始返回 TRUE,但在 1-2 秒后(无论传输文件的大小)它返回 FALSE。 这意味着该函数正在运行,但似乎问题出在参数上。

请告诉我哪里出错了?

可能从 string 到 TWideChar 的转换不正确。 或者目录的路径传递不正确,例如使用了不正确的斜杠。我尝试了不同的路径:

('C:/', 'C:\', 'C:', 'file://C:', 'file://C:/', '/', '\', '' )

什么不正确?请帮忙。我需要你的帮助。

【问题讨论】:

  • FWIW,我建议阅读我关于此类转换的文章,Pitfalls of Converting。它深入处理这些事情。
  • 谢谢!很棒的文章!有很多有用的东西。为什么 Google 搜索之前没有为我找到它...

标签: c delphi type-conversion


【解决方案1】:
procedure paprika_set_apikey(const key: PChar); cdecl; external 'sendanywhere.dll';

这是错误的。 PChar 是 PWideChar 的别名。类型应为PAnsiChar。

顺便说一句,您在传递文字时不需要PAnsiChar 或PWideChar 强制转换。删除它们以简化代码。

此外,您在参数中使用const 的含义与在C++ 代码中的含义不同,并且在任何情况下在外部声明中都毫无意义。我个人会删除这些修饰符并将指针作为纯值参数传递。

【讨论】:

  • 谢谢!我将第一个函数修改为:procedure paprika_set_apikey(key: PAnsiChar); cdecl; external 'sendanywhere.dll'; 当建议我删除 PAnsiChar 和 PWideChar 时,你是什么意思?你能举个这个函数的例子吗:PaprikaTask paprika_create_download(const wchar_t* key, const wchar_t* destDirPath); 它看起来像function paprika_create_download(key: Pointer; destDirPath: Pointer): PaprikaTask;吗?
  • 我没这么说。我说“你不需要PAnsiChar 或PWideChar 演员表”。你知道什么是演员表吗?如果没有,你应该查一下。我的意思是你不需要写PWideChar('correct_key'),可以写'correct_key'
  • 所以该函数可以是function paprika_create_download(key: PWideChar; destDirPath: PWideChar): PaprikaTask; cdecl; external 'sendanywhere.dll';,因为const 没有任何用途,并且当您调用它时,您不需要转换文字。你知道什么是字面意思吗?同样,如果你不知道,你需要知道。这个术语很关键。
  • 非常感谢。我知道这是什么意思。这只是我糟糕的英语解释。对不起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多