C#Interop Delphi DLL - c#

我在Delphi“ a.dll”(没有源代码)中编写了第三方DLL。

并且此DLL具有使用此签名的一种方法。

function GetAny(pFileName: String): String;

我无法从c#进行互操作调用,因为'String type'在delphi中具有私有访问权限。

因此,在delphi中构建另一个DLL来包装该调用。

德尔福

function GetAny(pFileName: String): String; external 'a.dll'

function GetWrapper(url : PChar) : PChar; stdcall;
begin
    Result := PChar(GetAny(url)); // I need avoid this String allocation, is throwing a exception.
end;

C#。

[DllImport("wrapper.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern IntPtr GetWrapper(String url);

在“ GetWrapper”内部,我对外部“ GetAny”进行了调用,结果是可以的(在delphi中,我可以调试),但是在我将结果返回c#之前,它引发了Exception。

IntPtr test = GetWrapper("a");
String result = Marshal.PtrToStringAnsi(test);

参考方案

您的包装DLL也不能调用GetAny,因为字符串是不能跨模块边界传递的托管Delphi类型。

问题在于,GetAny的返回值分配在一个模块中,而释放在另一个模块中。它在实现GetAny的DLL中分配,并在调用GetAny的DLL中释放。由于两个DLL使用不同的内存管理器,因此您最终将尝试取消分配在不同堆上分配的内存。

如果可以说服实现GetAny的DLL共享一个内存管理器,那么您可以轻松解决该问题。

我确实质疑您提出的事实。就目前而言,除非将DLL设计为与ShareMem一起使用,否则永远不能安全地调用该函数。

如果您准备泄漏内存,则可以尝试以下操作:

德尔菲

function GetAny(pFileName: string): PChar; external 'a.dll'

procedure GetWrapper(url: PChar; out value: WideString); stdcall;
var
  P: PChar;
begin
    P := GetAny(url);
    if Assigned(P) then
      Value := P
    else
      Value := '';
end;

C#

[DllImport("wrapper.dll"]
public static extern void GetWrapper(
    string url,
    [MarshalAs(UnmanagedType.BStr)]
    out string value
);

从线程调用ActiveX DLL - c#

我有一个ActiveX(COM)DLL,它可以进行Windows系统调用(例如ReadFile()和WriteFile())。我的GUI(使用Python或C#)在主GUI线程中创建DLL的实例。但是,为了从线程对其进行调用,无论使用C#还是Python,都必须在每个线程中创建DLL的新实例。 (作为一个补充说明,可以从C#中的线程调用原始实例,但这会阻塞主…

加载/卸载带有C#问题的C dll - c#

我在使用外部本机DLL时遇到问题。我正在ASP.NET 1.1 Web应用程序上工作,并具有通过DLLImport指令加载的此DLL。这就是我映射DLL函数的方式: [DllImport("somedllname", CallingConvention=CallingConvention.StdCall)] public static e…

使用存储在与主程序不同的文件夹中的参考库(dll)? - c#

(这可能是一个很明显的问题,但我不确定该问Bing / Google是什么)在VS2008(C#Winforms)项目中,有大量引用的第三方库。该项目使用“ Copy Local = True”,以便使各种DLL文件最终与已编译的应用程序位于同一文件夹中。为了清理问题,我想修改程序,使库都在子文件夹下。例如:C:\ MyProgram \->主程序文件…

C#使用Microsoft.Office.Interop.Excel读取Excel单元格值 - c#

我正在尝试提取Excel单元格值。我能够成功提取行值。我应该怎么做才能将每​​个单元格值从行中拉出?using Microsoft.Office.Interop.Excel; string pathToExcelFile = @"C:\Users\MyName\Desktop\Log.xls"; Application xlApp = n…

像在Java中一样,在Delphi Xe2中的控制台中进行打印 - java

我第一次在Delphi项目上工作,我曾经使用Java进行开发。有没有办法像在Java中那样在delphi的控制台中进行打印。System.out.println("Message"); 我曾经用来测试代码并查找错误(最初)。 参考方案 您必须使用Writeln(仅用于控制台应用程序)。{$APPTYPE CONSOLE} begin Wr…