0

管理されていないサードパーティ アプリから dll で ac# 関数を呼び出そうとしています - メタトレーダー

Calling C# dll from unmanaged codeのアドバイスに従いまし たが、文字列のマーシャリングに関する例は機能しません。

注:参照から整数加算の例(関数「Add」)を正常に呼び出しましたが、問題なくエンドツーエンドで動作するため、問題は文字列に関係していることがわかります。つまり、「ReplaceString」機能は機能しません。RobertGisiecke の Web サイトも見ましたが、そこには文字列の例がありません。または、愚かすぎて理解できません。

メタトレーダーで表示されるエラー メッセージは次のとおりです。

15:27:40 2009.11.10 00:01 MT4LibTest EURUSD、H1: 040B031B で dll 'Testme.dll' 重大なエラー c0000005 からの関数 'ReplaceString' 呼び出し。

プラットフォームは Windows Server 2012 (64 ビット) で、Metatrader は x86 プログラムであるため、x86 にコンパイルしました。

もう1つ:私はVSの世界であまり経験がないので、誰かが親切に助けてくれることを願っています

ありがとうございました

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;
    }

呼び出し機能 (メタトレーダー):

#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);

編集: 「スクリプト」の記述を可能にするメタトレーダー API は、完全な C++ 型を許可しないことを明確にする必要があります。したがって、char も wchar も、これらの型へのポインタもありません。「文字列」のみ。

4

1 に答える 1

0

解決策が見つかりました!

まず、回答してくださった皆様に感謝いたします。(私にとって)新しいテクノロジーを理解するのは少し大変でした)。@ジム:追加した編集を参照してください。MQL (メタトレーダー言語) は C++ に基づいている可能性がありますが、アプリケーションの設計者によって深刻な束縛を受けています。したがって、wchar 型はありません。@Simon: NuGet パッケージ「UnmanagedExports」への参照を追加すると、ラッパーが配置され、CIL フィックスアップが処理されるため、コードに集中できます。質問に含めたリンクには、これが詳しく説明されています。

そのままのコードには 2 つの問題がありました。

  1. 与えられたサンプル コードでは、c# 関数の文字列引数は LPWStr (ワイド文字列) として宣言されていました。デバッガーでそれらを見ると、中国語のような文字が含まれていることがわかりました。LPStr は正常に動作します。

    public static int ReplaceString(
        [In, Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder str,
        [MarshalAs(UnmanagedType.LPStr)]string a, 
        [MarshalAs(UnmanagedType.LPStr)]string b)
    
  2. サンプル コードには、呼び出し元 (ネイティブ) コードで引数として宣言された文字列へのポインターもありました。これを削除し、StringBuilder クラスを使用してマネージ C# コードの文字列を変更すると、うまくいきました。

    #import "MT4Lib.dll"
        int ReplaceString(string str,string a,string b);
        int Add(int x, int y);
    #import
    
于 2012-12-30T16:09:24.707 に答える