[英]passing structure from c# to C dll
我試圖學習足夠的C#,以便可以通過引用C DLL來傳遞結構。 但它永遠不會到達“ cFunction”。 如您在cFunction中所看到的,我將streamSubset值顯式設置為44; 但是回到c#部分時,它不會返回“ 44”。 這是C代碼:
typedef struct s_mPlot
{
double price[100];
int streamSubset;
} mPlot;
extern "C" __declspec( dllexport )
void cFunction(mPlot *Mplot){
Mplot->streamSubset = 44;}
//這是C#代碼
using System;
using Vibe.Function;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public class MPLOT
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public double [] price;
public int streamSubset;
}
namespace Vibe.Indicator{
public class myIdx : IndicatorObject {
[DllImport("C:\\Users\\joe\\mcDll.dll", CharSet = CharSet.Auto)]
public static extern void cFunction(
[In, MarshalAs(UnmanagedType.LPStruct)] MPLOT mPlot );
public myIdx(object _ctx):base(_ctx){}
private IPlotObject plot1;
protected override void Create()
{
MPLOT mPlot = new MPLOT();
mPlot.streamSubset = 2;
cFunction(mPlot);
if (mPlot.streamSubset == 44)
go();
}
}
}
我可以看到以下內容:
DllImport
屬性中指定cdecl
調用約定。 添加CallingConvention=CallingConvention.Cdecl
。 UnmanagedType.LPStruct
會增加一個間接級別。 但是,您傳遞的是引用類型的C# class
。 這意味着您正在將指針傳遞給指針。 那是間接的太多層次了。 首先,完全刪除[In, MarshalAs(UnmanagedType.LPStruct)]
。 然后您的代碼應該工作了。 如果您切換到MPLOT
的結構而不是類,則需要通過ref
來獲得間接MPLOT
。 我想我會有這樣的代碼:
[StructLayout(LayoutKind.Sequential)]
public struct MPLOT
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public double [] price;
public int streamSubset;
}
[DllImport("dllname.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void cFunction(
ref MPLOT mPlot
);
嘗試明確指定調用約定:
[DllImport("C:\\Users\\joe\\mcDll.dll", CallingConvention=CallingConvention.Cdecl CharSet = CharSet.Auto)]
VC默認情況下以調用約定cdecl
導出,但DllImport
默認情況下使用stdcall
。 因此,您必須至少明確指定其中之一,或者最好同時指定兩者。
用ref
替換[In, MarshalAs(UnmanagedType.LPStruct)]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.