相关疑难解决方法(0)

为什么WideString不能用作互操作的函数返回值?

我不止一次建议人们使用类型的返回值WideString进行互操作.

这个想法是a WideString和a一样BSTR.因为a BSTR是在共享COM堆上分配的,所以在一个模块中分配并在另一个模块中解除分配是没有问题的.这是因为所有各方都同意使用相同的堆,即COM堆.

但是,它似乎WideString不能用作互操作的函数返回值.

考虑以下Delphi DLL.

library WideStringTest;

uses
  ActiveX;

function TestWideString: WideString; stdcall;
begin
  Result := 'TestWideString';
end;

function TestBSTR: TBstr; stdcall;
begin
  Result := SysAllocString('TestBSTR');
end;

procedure TestWideStringOutParam(out str: WideString); stdcall;
begin
  str := 'TestWideStringOutParam';
end;

exports
  TestWideString, TestBSTR, TestWideStringOutParam;

begin
end.
Run Code Online (Sandbox Code Playgroud)

和以下C++代码:

typedef BSTR (__stdcall *Func)();
typedef void (__stdcall *OutParam)(BSTR &pstr);

HMODULE lib = LoadLibrary(DLLNAME);
Func TestWideString = (Func) GetProcAddress(lib, "TestWideString"); …
Run Code Online (Sandbox Code Playgroud)

delphi

48
推荐指数
2
解决办法
8541
查看次数

CoTaskMemAlloc的用法?

什么时候适合使用CoTaskMemAlloc?有人能举个例子吗?

windows com winapi

14
推荐指数
3
解决办法
1万
查看次数

为什么我需要在我的Delphi dll中使用Sharemem,它只使用WideString参数公开一个函数?

我有一个用Delphi编写的dll和测试应用程序.测试应用程序使用多个线程来调用dll导出的函数.导出的函数具有简单的线程安全实现.运行测试应用程序时会发生各种错误(访问冲突,无效指针操作,堆栈溢出等)或应用程序冻结.在某些情况下,应用程序完成没有错误.

请注意,这些错误仅在使用多个线程时发生(表面).从主线程调用函数时,一切正常.

我发现将ShareMem添加到dll和应用程序会停止所有这些错误.但我不明白为什么.据我所知,只有在dll和应用程序之间传递长字符串时才需要ShareMem.据我所知,WideString不是一个长字符串.

另外根据这篇文章,不应该要求ShareMem: 为什么Delphi DLL可以在不使用ShareMem的情况下使用WideString?

这是dll的来源:

library External;

uses
  Winapi.Windows;

type
  TMyType = class
  private
    FText: string;
  end;

function DoSomething(input: WideString; out output: WideString): Bool; stdcall;
var
  x: TObject;
begin
  x := TMyType.Create;
  try
    output := x.ClassName;
  finally
    x.Free;
  end;
  Result := True;
end;

exports
  DoSomething;
begin
end.
Run Code Online (Sandbox Code Playgroud)

这是测试应用程序:

program ConsoleTest;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.Windows,
  OtlParallel;

function DoSomething(input: WideString; out output: WideString): Bool; stdcall; external 'External.dll' name 'DoSomething';

var
  sResult: WideString;

begin
  try
    Parallel.&For(0, 500).Execute(procedure(value: Integer)
    var
      sResult: …
Run Code Online (Sandbox Code Playgroud)

delphi dll multithreading widestring omnithreadlibrary

9
推荐指数
1
解决办法
306
查看次数

在IIS网络服务器上调用Delphi DLL的ASP.NET Web应用程序,在返回PChar字符串时锁定

如果我不返回任何内容,则工作正常,或者返回一个整数.但如果我试图返回一个PChar,即...

result := PChar('')  or   result:= PChar('Hello')
Run Code Online (Sandbox Code Playgroud)

网络应用程序只是冻结,我看着它的内存数量在任务管理器中逐渐变得越来越高.

奇怪的是,DLL在VStudio调试服务器或C#应用程序上运行良好.我唯一能想到的就是IIS服务器在64位Windows上运行.

它似乎不是一个兼容性问题,因为我可以成功写入文本文件并从DLL中执行其他操作...我只是不能返回一个PChar字符串.

尝试使用PWideChar,尝试返回'something\0',尝试了我能想到的一切.不幸的是没有运气.

[DllImport("TheLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
private static extern string SomeFunction();

string result = SomeFunction();
Run Code Online (Sandbox Code Playgroud)

德尔福:

library TheLib;

function SomeFunction() : PChar export; stdcall;
begin
return PChar('');
end;

exports
    SomeFunction
Run Code Online (Sandbox Code Playgroud)

c# delphi iis interop

4
推荐指数
1
解决办法
1978
查看次数

从具有非托管导出的C#DLL返回字符串到Inno安装脚本

我有一个C#DLL,它使用Unmanaged Exports公开一个函数,它由Inno Setup Pascal脚本直接调用.此函数需要将字符串返回给Inno Setup.我的问题是如何实现这一目标?
我首选的方法是将Inno Setup中的缓冲区传递给C#函数,该函数将返回此缓冲区内的字符串.我想出了这段代码:

C#功能:

[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
static int Test([Out, MarshalAs(UnmanagedType.LPWStr)] out string strout)
{
   strout = "teststr";
   return strout.Length;
}
Run Code Online (Sandbox Code Playgroud)

Inno安装脚本:

function Test(var res: String):Integer; external 'Test@files:testdll.dll stdcall';

procedure test1; 
var
    Res: String;
    l: Integer;
begin
    SetLength(Res,256);
    l := Test(Res);
    { Uncommenting the following line causes an exception }
    { SetLength(Res,l); }
    Log('"Res"');
end;
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,Res变量为空(我在日志中看到"")

如何从此DLL返回一个字符串?

请注意,我使用的是Inno Setup的Unicode版本.我也不想使用COM调用此函数,也不想在DLL中分配缓冲区并将其返回给Inno Setup.

c# dll inno-setup unmanagedexports

4
推荐指数
1
解决办法
2589
查看次数

在Delphi中编写DLL以从其他语言调用

这将是我第一次尝试在Delphi中编写DLL以从其他语言调用.

我已经做了很多谷歌搜索并看到一些好的指针,但没有详尽无遗(至少,我有问题,在Embarcadero材料中没有找到答案).

我想知道这个警告列表是否有效,或者我是否遗漏了什么,如果有人可以在下面提出我的问题.

  • 如果我希望我的DLL可以从其他语言调用,那么我不能使用该ShareMem单位.
  • 我不能使用这种String类型,应该坚持下去PChar
  • 如果我想返回一个字符串,则调用者应该给我一个缓冲区,它写入(我 alloctae内存为我自己,即使我提供了一个常规的事后释放它)
  • 我应该坚持像(integetrPChar其他人一样)的简单类型吗?

几个问题:

  • comipler禁止我导出枚举和常量.我只是没有正确宣布它们吗?我想调用Delphi s/w能够使用枚举元素和所有调用者能够使用常量.
  • 我不应该使用任何结构,因为编译器之间的字节对齐可能存在差异.所以,如果我不能接受strectures作为参数.我想我应该只有integers和PChars 的长参数列表?
  • 我可以接受数组作为参数,或者边界对齐是否会造成危险?
  • 我可以接受/返回花车/双打吗?
  • 布尔值?或者我坚持"zer0 ===假,其他一切都是真的"?

  • 还有什么我应该知道的吗?

在此先感谢您的帮助

delphi dll enums export

3
推荐指数
1
解决办法
318
查看次数