1

よし、これで契約だ。NinjaTrader プラットフォーム用に作成されたインジケーター (ninjascript で作成されています... 基本的に C# にプラットフォーム固有のコードが追加されています) を使用して C++ dll をインターフェイスしようとしています。dll を意図したとおりに動作させるには、構造体配列をインジケーターから dll に渡すことができる必要があります。インジケーター コードでは、ref を介して構造体配列を渡しています。dll では、構造体配列をポインターとして受け入れようとしています。これにより、大量の情報を NinjaTrader に戻す方法を考え出すことなく、dll の内容を編集することができます。基本的に、dll は構造体配列ポインターを受け取り、内容に直接アクセスできるようにします。次に、dll 関数が bool true フラグを Ninja に返すと、struct 配列にアクセスし、情報をチャートにレンダリングします。シンプルですね。私もそう思いました。

これが問題です。NinjaTrader は安全でないコードを許可しません。そのため、構造体配列を dll に渡してポインタとして受け取ろうとすると、すぐにプラットフォームがクラッシュします。構造体配列を ref (*&) へのポインターとして受け取った場合は機能しますが、制御が Ninja に戻されると、構造体配列で行われたすべての編集は存在しなくなります。

そこで、このプロセスを高速化するために、非常に簡単なインジケーターと、私がやろうとしていることを示す dll コード セットを作成しました。忍者インジケータコードは次のとおりです。

[StructLayout(LayoutKind.Sequential)]
public struct TestStruct
{
    public int x, y;    
}
TestStruct[] test = new TestStruct[2];

protected override void OnBarUpdate()
{
    if(CurrentBar < Count - 2) {return;}
    test[0].x = 10;
    test[0].y = 2;
    test[1].x = 0;
    test[1].y = 0;

    Print(GetDLL.TestFunk(ref test));
    Print("X0: " + test[0].x.ToString() + "  Y0: " + test[0].y.ToString());
    Print("X1: " + test[1].x.ToString() + "  Y1: " + test[1].y.ToString());
}

class GetDLL
{
    GetDLL() {}
    ~GetDLL() {}
    [DllImport("testdll.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "TestFunk")]
    public static extern int TestFunk(
            [In,MarshalAs(UnmanagedType.LPArray)] ref TestStruct[] test );
}

そして今、C++ dll コード:

#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

struct TestStruct
{
   int x, y;
};

extern "C" __declspec(dllexport) int __stdcall TestFunk( TestStruct *testy )
{
   testy[1].x = 20;
   testy[1].y = 9;
   int one = testy[1].x;
   int two = testy[1].y;

   return (one + two);
}

上記で貼り付けたこのコードにより、チャートにインジケーターを配置してアクティブになった瞬間に NinjaTrader がクラッシュすることを覚えておいてください。クラッシュしないようにする唯一の方法は、C++ TestFunk 関数の引数をTestStruct *&testyorに変更することです。演算子も変更する必要があることTestStruct **testyに注意してください。.->

私がすべて言ったので、この制限を回避して実際のポインターにアクセスする方法を知っている人はいますか?クラッシュしない?

4

1 に答える 1