You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 11 DLL向.NET 7 C# API返回未知长度字符串求助

Delphi 11 DLL返回字符串给.NET 7 C#的正确实现

核心问题分析

你遇到的所有错误本质上是两个问题:

  1. 调用约定不匹配:Delphi默认的函数调用约定是register(快速调用),而你C#中指定的是CallingConvention.StdCall,栈参数传递方式不一致导致栈损坏,引发运行时错误或访问违规。
  2. 字符串类型兼容性:Delphi私有的string类型(UnicodeString)无法被CLR识别;直接返回PChar会存在内存分配/释放的所有权问题;WideString本身是COM标准的BStr,但因为调用约定错误才导致报错。

推荐解决方案:使用COM BStr(WideString)

这是跨语言字符串传递最安全的方式,BStr由COM堆分配,CLR可以自动完成内存释放,无需手动管理。

修改后的Delphi代码

library Project1;
uses
  SysUtils;

{$R *.res}

// 显式指定stdcall调用约定,匹配C#的StdCall
function TestWide(aInput: WideString): WideString; stdcall;
begin
  // 可返回任意长度字符串,示例拼接输入内容
  Result := 'Delphi返回:' + aInput;
end;

exports
  TestWide;

begin
end.

对应的C#代码

using System.Runtime.InteropServices;

internal class Program
{
    [DllImport("Project1.dll", EntryPoint = "TestWide", 
               CallingConvention = CallingConvention.StdCall, 
               CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.BStr)]
    public static extern string TestWide([MarshalAs(UnmanagedType.BStr)] string input);

    private static void Main(string[] args)
    {
        try
        {
            string result = TestWide("Hello from C#");
            Console.WriteLine(result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"错误:{ex.Message}");
        }
    }
}

替代方案:使用CoTaskMemAlloc分配字符串

如果需要返回PChar类型,必须确保内存由CoTaskMemAlloc分配(CLR会自动用CoTaskMemFree释放):

Delphi代码

function TestCoTaskString(aInput: PWideChar): PWideChar; stdcall;
var
  outputStr: WideString;
  strLen: Integer;
begin
  outputStr := '处理结果:' + aInput;
  strLen := Length(outputStr) + 1; // 包含终止符
  // 用COM堆分配内存
  Result := CoTaskMemAlloc(strLen * SizeOf(WideChar));
  if Assigned(Result) then
    StringToWideChar(outputStr, Result, strLen);
end;

exports
  TestCoTaskString;

C#代码

[DllImport("Project1.dll", EntryPoint = "TestCoTaskString", 
           CallingConvention = CallingConvention.StdCall, 
           CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string TestCoTaskString(string input);

各测试函数错误原因说明

  • TestWide报错(Runtime error 203):调用约定不匹配导致栈损坏,给Delphi函数添加stdcall修饰符即可解决。
  • TestPChar报错:同样是调用约定不匹配,且返回的输入PChar内存由C#管理,可能已被回收;若Delphi分配PChar,C#无法释放Delphi堆内存,会引发泄漏或错误。
  • TestString报错(AccessViolation):Delphi的string是私有引用计数类型,CLR无法解析其内部结构,直接返回会触发内存访问违规。

内容的提问来源于stack exchange,提问作者Matt Baech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:58:22