繁体   English   中英

Delphi和C / C ++ DLL

[英]Delphi and C/C++ DLL

我有一个使用BTMemoryModule并从DLL导入/调用函数的delphi应用程序。 DLL是用C / C ++编写的。

delphi应用程序将原始的pwidechar(4字节数组或widechars数组)发送给函数。

我没有C / C ++伪代码,但它看起来像这样:

type
 TMyFunc = function ( p  : pointer ): pointer; stdcall;

procedure anynamehere();
var
 Addr     : TMyFunc;
 MyString : WideString;
begin
 [...]
  Addr := BTMemoryGetProcAddress('mydll.dll', 'ExportedFunc');
  MyString := 'TEST';
 [...]
 ExportedFunc (pwidechar(MyString));
 MessageBoxW (0, pwidechar(MyString), '', 0);
end;

DLL现在应该具有指向MyString var的原始指针。 delphiapp中的过程保持活动状态(直到DLL ExportedFunc完成)。 因此,在过程结束后,不会处理MyString var。 我现在的问题是:是否可以在DLL中更改MyString的值? (技术上可行...)但是如何? 该字符串以null结尾,因此用户知道指针的长度。 但是,如果C ++ DLL更改了值,用户是否还没有分配新的空间? 还是自动发生?

谢谢你的帮助。

欢迎DLL根据需要更改指向的内存,并且它也不需要知道MyString的地址。 它只需要知道存储在 MyString的地址,这正是您已经传递给它的地址。 由于该函数收到一个指向以null终止的WideChar值数组的指针,因此应这样声明该函数:

void* __stdcall ExportedFunc(wchar_t* arg);

它可以使用wcslen找出缓冲区的长度,然后以通常的方式修改缓冲区的内容。 例如:

{
  size_t const len = wcslen(arg);
  for (size_t i = 0; i < len; ++i)
    if (arg[i] == 'a')
      arg[i] = 'e';
  return 0;
}

您可以根据需要让它返回其他指针值,但是由于调用方会忽略它,因此在这种情况下并不重要。

当调用者为MyString分配值时,操作系统将通过SysAllocString代表程序自动分配空间。 然后,调用者将该缓冲区传递给DLL,然后DLL可以对其进行修改。 调用者之后不需要对缓冲区做任何特殊的事情。 当调用函数结束并且MyString超出作用域时,Delphi将自动调用SysFreeString

您还可以删除PWideChar类型PWideChar并声明该函数以在Delphi中接收WideString ,在C ++中为BSTR 除了使用SysStringLen而不是wcslen之外,您还可以在DLL中进行所有相同的字符串操作。 您可以将MyString直接传递给该函数:

ExportedFunc(MyString);

C ++代码可以更改传入的pwidechar数组的内容,但不能更改delphi理解的字符串的长度,因为C ++代码本身无法理解delphi样式的字符串。 它收到的只是一个wchar *参数。

如果要对字符串进行重大更改(例如,使其更长),则需要使用SetLength(MyString, size)在调用程序中分配至少与您所需的空间一样的SetLength(MyString, size) ,然后检查返回的长度,因此然后SetLength(MyString, retSize)在字符串上调用SetLength(MyString, retSize)以使其成为返回的大小。

同样,通常会针对缓冲区溢出等问题做出警告。

我注意到该函数返回一个指针。 如果C ++代码使用new()分配内存,则由于两个内存分配系统不同,因此无法通过Delphi代码管理此内存。

DLL传递了一个指向缓冲区的指针。 DLL完全有可能修改该缓冲区。 DLL可以修改您的代码传递给它的4个宽字符中的任何一个。 它还可以修改第五个字符,即空终止符。

但是,DLL无法创建新缓冲区,并且调用代码无法看到该新缓冲区。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM