调用DLL中的对象的方法返回值为string时报错

31 篇文章 0 订阅

调用DLL中的对象的方法返回值为string时报错!!!!
问题:

对象TDllNumber在objdll.dll中定义:

objdll.dll输出一个函数:CreateObject


type
TDllNumber=class
public
function GetOk:string;virtual;abstract;
end;
TDllNumber1=class(TDllNumber)
public
constructor create;
function GetOk:string;override;
end;
function CreateObject:TDllNumber;export;

implementation

constructor TDllNumber1.create;
begin
inherited create;
end;

function TDllNumber1.GetOk: string;
begin
result:='ok';
end;
function CreateObject:TDllNumber;
begin
Result:=TDllNumber1.Create;
end;


在程序中调用对象:
type

TDllNumber=class
public
function GetOk:string;virtual;abstract;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

function CreateObject:TDllNumber;stdcall;external 'objdll.dll';
implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
Ok:string;
TestObj:TDllNumber;
begin
TestObj:=CreateObject;
Ok:=TestObj.GetOk;
ShowMessage(ok);
TestObj.Free;
end;

当程序运行到button1click最后是包错:
Invalid pointer Operation!!!
但是为integer,pchar不报错!!!!


总结:
1。 在dll中定义返回string字符串的函数时,如果没有特殊处理调用该函数
在退出调用该函数的过程(函数/事件)时,会出现以下错误:
Invalid Pointer Operator!

2。当在单元中添加ShareMem时,在退出程序的时候会出现同样的错误

3。当在调用dll的项目文件中(不是在单元文件)添加ShareMem时,能够正常
运行.

4. String类型是Borland自定的特殊类型,使用起来真是无比方便,
但是,它需要borladmm.dll的支持,在动态链接库中想使用STRING类型
要经过特殊的手段,因此还是使用PCHAR类型吧。PCHAR也挺方便的。
另外如果没有特殊处理的话: WideString-可以
AnsiString-不可以

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C# 调用 C++ DLL 的 std::string 类型方法,需要使用 `StringBuilder` 类来接收返回值,同需要在 C# 定义与 C++ 方法签名相匹配的委托类型,并使用 `Marshal.GetDelegateForFunctionPointer` 方法DLL 导出函数的指针转换为委托对象。以下是一个示例: C++ DLL 的类和方法: ```cpp #include <string> class MyCppClass { public: std::string MyCppMethod(const std::string& str) { return "Hello " + str + " from C++!"; } }; extern "C" { __declspec(dllexport) MyCppClass* CreateMyCppClass() { return new MyCppClass(); } __declspec(dllexport) void DeleteMyCppClass(MyCppClass* p) { delete p; } __declspec(dllexport) void MyCppClass_MyCppMethod(MyCppClass* p, const char* str, char* buffer, int bufferSize) { std::string s(str); std::string result = p->MyCppMethod(s); strncpy(buffer, result.c_str(), bufferSize); } } ``` C# 代码: ```csharp using System; using System.Runtime.InteropServices; using System.Text; class Program { [DllImport("MyCppDll.dll")] public static extern IntPtr CreateMyCppClass(); [DllImport("MyCppDll.dll")] public static extern void DeleteMyCppClass(IntPtr p); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void MyCppClass_MyCppMethodDelegate(IntPtr p, string str, StringBuilder sb, int bufferSize); static void Main() { IntPtr p = CreateMyCppClass(); try { MyCppClass_MyCppMethodDelegate MyCppClass_MyCppMethod = (MyCppClass_MyCppMethodDelegate)Marshal.GetDelegateForFunctionPointer( Marshal.GetFunctionPointerForDelegate((MyCppClass_MyCppMethodDelegate)delegate { }), typeof(MyCppClass_MyCppMethodDelegate) ); StringBuilder sb = new StringBuilder(256); MyCppClass_MyCppMethod(p, "World", sb, sb.Capacity); Console.WriteLine(sb.ToString()); } finally { DeleteMyCppClass(p); } } } ``` 在上述代码,我们首先声明了从 C++ DLL 导入的函数 `CreateMyCppClass` 和 `DeleteMyCppClass`,它们分别用于创建和销毁 C++ 类的实例。接下来,我们定义了一个与 C++ 方法签名相匹配的委托类型 `MyCppClass_MyCppMethodDelegate`,并使用 `Marshal.GetDelegateForFunctionPointer` 方法DLL 导出函数 `MyCppClass_MyCppMethod` 的指针转换为委托对象。 在调用 C++ 类的方法之前,我们需要先创建一个 C++ 类的实例,并将其封装在 `IntPtr` 对象。在调用 C++ 类的方法,我们使用上述委托对象调用 C++ DLL 的函数 `MyCppClass_MyCppMethod`,并使用 `StringBuilder` 类来接收返回值。需要注意的是,在调用 `MyCppClass_MyCppMethod` 之前,我们需要先创建一个足够大的 `StringBuilder` 对象,并将其容量传递给 C++ DLL 方法,以确保能够接收到完整的字符串。最后,我们使用 `DeleteMyCppClass` 函数销毁 C++ 类的实例。 需要注意的是,在 C++ DLL ,函数的参数类型必须为基本类型或指针类型,不能使用引用类型。另外,在 C++ DLL 使用的字符串编码格式必须与 C# 使用的字符串编码格式相同,否则可能会出现乱码问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值