作成したcコードから文字列を取得するのに問題があります。
まず、一般的に実現されていない背景情報:TAPIAPIからTAPITSPのユーザーが読み取り可能な文字列を受け取りたいのですが。ドライバー名を保存された文字列に一致させることに依存する半実行可能なTAPIソリューションを実装しましたが、お客様の1人が他の方法で動作することを拒否する(Alcatel)PBXを持っているため、代わりに永続的な回線IDで動作するようにこれを変更したいと思います。
Cでは、ヘッダーファイルで関数を次のように定義します。
__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName);
関数は次のように記述されます。
__declspec(dllexport) void GetDeviceName(long DeviceId, wchar_t* DeviceName)
{
//tapi code here...
//copy the string to DeviceName
wcscpy(DeviceName, (wchar_t*)((char *)devCaps + devCaps->dwLineNameOffset));
}
上で述べたように、これは最終的には何か便利なことをしますが、今のところ、abcがwchar_t * / StringBuilderに配置されていて、C#でそれを見ることができれば幸いです。
C#では、関数を次のように定義します。
[DllImport("SBW.Tapi.TapiInterop.dll", CharSet = CharSet.Auto)]
static extern void GetDeviceName(long DeviceId, StringBuilder DeviceName);
文字列は不変であり、DeviceNameをCで設定したいのでDeviceNameをStringBuilderとして定義します(これはMSによって推奨されています)。void
私はまた、それが何かにも影響を与えるという細い希望に基づいてリターンタイプを設定しました(部分的な疑似科学的説明については、この半有用なモノの記事を参照してください)。
そしてそれをそう呼んでください:
StringBuilder name = new StringBuilder();
name.EnsureCapacity(100);
long n = 0;
GetDeviceName(n, name);
実行中のプロセスにデバッガーを接続し、ブレークポイントを設定すると、Cコードで、StringBuilderが何らかの形で変質し、アンマネージコードにnullポインターとして提供されていることに気付きます。
その後、AccessViolationExceptionがC#でスローされます。
何が問題なのですか?
longパラメータを削除すると役立ちます。CのDeviceNameパラメーターに「abc」を追加できます。ただし、その長い変数が必要です。その長いパラメータをそこに置くことによってクラッシュを強制するために、私は間違っているか動揺しているのですか?