接收字符串从C ++ DLL数组在Delphi 7 [英] Receive an array of string from a c++ DLL in Delphi 7

查看:258
本文介绍了接收字符串从C ++ DLL数组在Delphi 7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创造C ++中的DLL,它会在一个Delphi 7项目中使用。

I am creating a DLL in C++, it would be used in a Delphi 7 project.

此问题是关系到<一个href=\"http://$c$creview.stackexchange.com/questions/43347/produce-an-array-of-strings-from-a-single-string/43398?noredirect=1#43398\">this 之一,我在那里present两个功能验证为gettoken 只是现在他们将完成在C ++和字符串数组为gettoken 产生将被送回德尔福。

This question is related to this one, where I present two functions Validate and GetToken only that now they will be done in C++ and the array of strings GetToken produces would be sent back to Delphi.

这些问题是我不知道如何创建,将返回字符串数组在C ++中DLL中的函数,我不知道它将如何存放在Delphi中进一步使用。

The problems is I don't know how to create the function in the dll that will return the array of string in c++, and I don't know how it would be stored for further use in Delphi.

该函数的声明如下:

函数为gettoken(连锁:字符串):Arrayofstring;

推荐答案

根据您的code审查,德尔福code预计该功能具有以下特征:

According to your code review, the Delphi code expects the function to have the following signature:

function GetToken(Chain: AnsiString): array of AnsiString;

您无法用C这样的函数++。 C ++不知道什么是德尔福字符串是,它不知道什么是德尔福动态数组是,无论是。这两种类型的需要从德尔福的内存管理器,你的C ++ DLL将无法获得分配。此外,C ++不知道如何使用Delphi的注册调用约定。

You cannot write such a function in C++. C++ doesn't know what Delphi strings are, and it doesn't know what Delphi dynamic arrays are, either. Both types need to be allocated from Delphi's memory manager, which your C++ DLL won't have access to. Furthermore, C++ doesn't know how to use Delphi's register calling convention.

该DLL接口被设计不当。除非它是设计师的的有意的排除所有其他语言的DLL不应该使用特定于语言的类型。 (在这种情况下,即使以后在同一语言版本的排除,因为 AnsiString类型的定义德尔福2009年改为包括德尔福7将不能正确地处理更多的元数据。 )最安全的调用约定选择一般 STDCALL 。这就是一切在Windows API中使用。

The DLL interface was designed poorly. DLLs should never use language-specific types unless it was the designer's intention to exclude all other languages. (And in this case, even later versions of the same language are excluded because the definition of AnsiString changed in Delphi 2009 to include more metadata that Delphi 7 won't handle properly.) The safest calling convention to choose is generally stdcall. It's what everything in the Windows API uses.

有一个更好的界面将使用通用于所有的语言类型,它会决定使用内存管理这是普遍访问的。有几种常见的方式来做到这一点。例如:

A better interface would use types that are common to all languages, and it would dictate the use of memory management that's accessible universally. There are several common ways to do that. For example:


  • 中的字符串返回字符的简单空终止阵列 - PAnsiChar Delphi中; 的char * 在C ++中。该DLL分配缓冲区的字符串,还分配一个缓冲器,用于这些字符串的数组。当主机应用程序正在使用阵列和串结束时,它调用由所述的DLL释放它分配的内存DLL导出另一个函数。这是由所用的模型,例如, 的FormatMessage ;当主机程序完成与消息字符串,它调用 LocalFree

  • The strings are returned as simple nul-terminated arrays of characters — PAnsiChar in Delphi; char* in C++. The DLL allocates buffers for the strings, and also allocates a buffer for the array of those strings. When the host application is finished using the array and the strings, it calls another function exported by the DLL wherein the DLL frees the memory it allocated. This is the model used by, for example, FormatMessage; when the host program is finished the with message string, it calls LocalFree.

type
  PStringArray = ^TStringArray;
  TStringArray = array[0..Pred(MaxInt) div SizeOf(PAnsiChar)] of PAnsiChar;
function GetToken(Char: PAnsiChar): PStringArray; stdcall;
procedure FreeStringArray(StringArray: PStringArray); stdcall;

char** __stdcall GetToken(char const* Chain);
void __stdcall FreeStringArray(char** StringArray);


  • 使用COM返回BSTR对象的SAFEARRAY。这是类似previous技术,但内存管理是由COM而不是由你的DLL中定义,所以有需要通过接口的任何一方来定义更少的东西。

  • Use COM to return a safearray of BStr objects. It's similar to the previous technique, but the memory management is defined by COM instead of by your DLL, so there's less stuff that needs to be defined by either party of the interface.

    传递一个回调函数的DLL,所以不是返回一个字符串数组,该DLL只是每次标识字符串调用函数一次。然后,你不必定义什么任何数组的样子,和每个字符串的使用期限可以是回调调用的只是一生 - 如果主机应用程序需要一个副本,它可以这样做。新的函数签名会是这个样子:

    Pass a callback function to the DLL, so instead of returning an array of strings, the DLL just calls the function once for each string it identifies. Then you don't have to define what any array looks like, and the lifetime of each string can be just the lifetime of the callback call — if the host application wants a copy, it can do so. The new function signature would look something like this:

    type
      TTokenCallback = procedure(Token: PAnsiChar); stdcall;
    procedure GetToken(Chain: PAnsiChar; ProcessToken: TTokenCallback); stdcall;
    

    typedef void (__stdcall* TokenCallback)(char const* Token);
    void __stdcall GetToken(char const* Chain, TokenCallback ProcessToken);
    


  • 如果你不是谁设计的DLL接口一个,那么你就需要依靠谁做的人,并得到它改为非德尔福code更容易获得。如果你不能做到这一点,那么最后的选择是写在Delphi中一个DLL,包你的DLL的参数按摩到东西两侧理解。

    If you're not the one who designed the DLL interface, then you need to lean on the folks who did and get it changed to be more accessible to non-Delphi code. If you can't do that, then the final alternative is to write a DLL in Delphi that wraps your DLL to massage the parameters into something each side understands.

    这篇关于接收字符串从C ++ DLL数组在Delphi 7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆