在C#中使用Delphi 7中编译的DLL

WeG*_*ars 2 c# delphi dll

我需要在我的C#应用​​程序中使用Delphi 7中的DLL(硬件ID提取器).

此DLL导出的函数是:

导出功能:

// CPU
function GetCPUSpeed: Double;
function CPUFamily: ShortString; { Get cpu identifier from the windows registry }
function GetCpuTheoreticSpeed: Integer; { Get cpu speed (in MHz) }
function IsCPUIDAvailable: Boolean; Register;
function GetCPUID (CpuCore: byte): ShortString;
Function GetCPUVendor: ShortString;

// RAM
function MemoryStatus (MemType: Integer): cardinal; { in Bytes }
function MemoryStatus_MB (MemType: Integer): ShortString; { in MB }

// HDD
function GetPartitionID (Partition : PChar): ShortString; { Get the ID of the specified patition. Example of parameter: 'C:' }
function GetIDESerialNumber(DriveNumber: Byte ): PChar; { DriveNr is from 0 to 4 }
Run Code Online (Sandbox Code Playgroud)

我知道(显然)Delphi中的字符串不是以null结尾并且是字节(ASCII).但我不知道如何将这些Delphi字符串映射到C#.

谢谢.

Dar*_*rov 6

以下是如何在C#中声明GetCPUSpeed函数的示例:

class Program
{
    [DllImport("the_name_of_the_delphi_library.dll")]
    public static extern double GetCPUSpeed();

    static void Main(string[] args)
    {
        double cpuSpeed = GetCPUSpeed();
        Console.WriteLine("CPU speed: {0}", cpuSpeed);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有其他可以尝试的声明:

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern string CPUFamily();

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern int GetCpuTheoreticSpeed();

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern bool IsCPUIDAvailable();

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern string GetCPUID(byte cpuCore);

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern string GetCPUVendor();

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern uint MemoryStatus(int memType);

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern string MemoryStatus_MB(int memType);

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern string GetPartitionID(char partition);

[DllImport("the_name_of_the_delphi_library.dll")]
public static extern string GetIDESerialNumber(byte driveNumber);
Run Code Online (Sandbox Code Playgroud)


mgh*_*hie 6

问题来自您设计导出功能的方式.DLL(除其他外)是一种机制,用于以可以从以不同编程语言编写的应用程序(或其他DLL)使用的方式提供代码.

看看Windows API,有很多函数返回文本.不幸的是,这是以很多不同的方式完成的,Windows API没有真正的标准.但是,我很确定你不会找到一个以你的方式返回"字符串"(Pascal或C(空终止)字符串)的函数.原因很简单:这会使不同的模块使用不同的编程语言变得非常困难甚至不可能.你的DLL会为字符串分配内存,一旦调用者完成字符串,就需要释放内存.因此,两个模块都需要共享这片内存的管理器.C#程序如何使用你的DLL,看到他们使用完全不同的内存管理器?

从DLL获取字符串值的习惯方法是使用预分配缓冲区和参数中的缓冲区长度调用函数,让函数用字符串内容填充该缓冲区,并让函数结果表示成功或失败.例如,传递大小不足的缓冲区将是失败的一个原因.不同的Windows API函数以不同的方式处理这个问题,最简单的方法可能是用常量定义最大字符串长度,MAX_PATH例如类似.

要解决您的问题,您应该使用一个知道如何从C#调用的Windows API函数,并在缓冲区中返回字符串结果,作为示例.在此示例之后为导出的函数建模,并且应该很容易从C#程序中调用它们.

编辑:

我记得我曾经看过一个类似的问题(如何从Delphi中制作的DLL中导入一个函数?),现在看起来我发现它也是你的.

您之后写道,您没有该DLL的源代码,因此更改导出的函数是不可能的.你可以做的是在Delphi中创建一个包装DLL(或COM对象),调用原始文件HardwareIDExtractor.dll并在其上提供一个理智的API.这样您就可以同时提供导出函数的AnsiChar和WideChar版本.

如果你想减少混乱(两个必要的DLL而不是一个),你也可以将原始HardwareIDExtractor.dll资源作为资源放入你的包装DLL中,如本博客文章中所述:在Delphi程序中使用存储为Resources的DLL