简体   繁体   English

从C#dll调用/编组字符串到非托管代码

[英]Calling/Marshalling strings from c# dll to unmanaged code

I'm trying to call ac# function in a dll from an unmanaged 3rd party app - metatrader 我正在尝试从非托管的第三方应用程序调用dll中的ac#函数-MetaTrader

I have followed advice from Calling C# dll from unmanaged code however, the example about marshalling strings does not work. 我遵循了从非托管代码调用C#dll的建议,但是,有关编组字符串的示例不起作用。

Note: I have successfully called the integer addition example from the reference (function "Add"), and it works end to end with no problems, so I know the issue is to do with strings. 注意:我已经成功地从引用(函数“ Add”)中调用了整数加法示例,并且它可以毫无问题地端到端地工作,因此我知道问题与字符串有关。 Ie, the "ReplaceString" function does not work. 即,“ ReplaceString”功能不起作用。 I have also looked atRobertGisiecke website, but there is not a string example there, or I am too dumb to figure it out. 我也看过RobertGisiecke网站,但是那里没有字符串示例,或者我太笨了,无法弄清楚。

The error message I get in metatrader is: 我在metatrader中收到的错误消息是:

15:27:40 2009.11.10 00:01 MT4LibTest EURUSD,H1: function 'ReplaceString' call from dll 'Testme.dll' critical error c0000005 at 040B031B. 15:27:40 2009.11.10 00:01 MT4LibTest EURUSD,H1:从DLL'Testme.dll'严重错误c0000005的函数'ReplaceString'调用在040B031B。

Platform is Windows Server 2012 (64bit) and I have compiled to x86 because Metatrader is an x86 program 平台是Windows Server 2012(64位),由于Metatrader是x86程序,因此我已编译为x86

One more thing: I am not very experienced in VS world, so Im hoping someone can be kind enough to help 还有一件事:我在VS世界上不是很有经验,所以我希望有人能帮助我们

Thank you 谢谢

C# code: C#代码:

[DllExport("ReplaceString", CallingConvention = CallingConvention.StdCall)]
    public static int ReplaceString(
        [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder str,
        [MarshalAs(UnmanagedType.LPWStr)]string a, 
        [MarshalAs(UnmanagedType.LPWStr)]string b)
    {
        str.Replace(a, b);

        if (str.ToString().Contains(a)) return 1;
        else 
            return 0;
    }

Calling function (Metatrader): 调用函数(Metatrader):

#import "MT4Lib.dll"
    int ReplaceString(string & str,string a,string b);
    int Add(int x, int y);
#import
    string str="A quick brown fox jumps over the lazy dog";
    string stra = "fox";
    string strb = "cat";        

    Print(str);
    Print(ReplaceString(str,stra,strb));
    Print(str);

EDIT: I should make clear that the metatrader API that allows one to write 'scripts' does not allow full C++ types. 编辑:我应该明确指出,允许一个人编写“脚本”的metatrader API不允许使用完整的C ++类型。 So there is no char, no wchar and certainly no pointers to these types. 因此,没有字符,没有wchar,当然也没有指向这些类型的指针。 Only "string". 只有“字符串”。

Solution found! 找到解决方案!

First off, thank yous to everyone who responded. 首先,感谢所有回答的人。 Getting to grips with new technology (for me) has been a little challenging). 掌握新技术(对我而言)有点挑战。 @Jim: See the EDIT I added. @Jim:请参阅我添加的编辑。 MQL (the metatrader language) may be based on C++ but has been seriously shackled by the designers of the application. MQL(元交易者语言)可能基于C ++,但已被应用程序设计者严重束缚。 So no wchar types. 所以没有wchar类型。 @Simon: Adding a reference to NuGet package "UnmanagedExports" will place wrappers and handle CIL fixups for you, so you can concentrate on your code. @Simon:添加对NuGet包“ UnmanagedExports”的引用将为您放置包装并处理CIL修复,因此您可以专注于代码。 The link I included in the question details this. 我在问题中包含的链接对此进行了详细说明。

There were two issues with the code as is: 代码本身有两个问题:

  1. In the sample code given, string arguments in c# function were declared as LPWStr (Wide strings). 在给出的示例代码中,c#函数中的字符串参数声明为LPWStr(宽字符串)。 Looking at them in debugger showed they had Chinese-looking characters in them. 在调试器中查看它们时,发现它们中具有汉字字符。 LPStr works fine. LPStr正常工作。

     public static int ReplaceString( [In, Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder str, [MarshalAs(UnmanagedType.LPStr)]string a, [MarshalAs(UnmanagedType.LPStr)]string b) 
  2. Sample code also had a pointer to string declared as an argument in the caller (native) code. 示例代码还具有一个指向字符串的指针,该字符串在调用方(本机)代码中声明为参数。 Removing this, and using StringBuilder class to change the string in the managed c# code, worked. 删除它,并使用StringBuilder类更改托管c#代码中的字符串,可以正常工作。

     #import "MT4Lib.dll" int ReplaceString(string str,string a,string b); int Add(int x, int y); #import 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM