【问题标题】:C# - Call C++ DLL function whit refC# - 使用 ref 调用 C++ DLL 函数
【发布时间】:2021-03-16 16:52:27
【问题描述】:

我正在尝试从我的 C# 代码中调用 C++ 中的 DLL 函数。

DLL 函数代码和结构(C++):

typedef struct{
    Operacion RespuestaOperacion; 
    char var1[256];           
    int var2;                      
    char var3[33];                    
    char var4[1025];                 
    char var5[20];                       
    char var6[11];                  
    char var7[7];                      
} TResultado;

typedef void (WINAPI *TPROC_PAY_VENTA)(long Importe, bool ProcessMessages, TResultado *Resultado);

我的 C# 代码:

[StructLayout(LayoutKind.Sequential)]
public struct TResultado
{
    public Operacion RespuestaOperacion;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string var1;
    public int var2;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
    public string var3;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1025)]
    public string var4;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string var5;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string var6;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
    public string var7;   
}

[DllImport("DLLName.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Pay_Venta(long importe, bool ProcessMessages, ref TResultado Resultado);

TResultado Resultado = new TResultado();
long cent = 1;

CRPayIUN_Venta(cent, true, ref Resultado);

错误!!!

我遇到的问题是,当通过函数时它告诉我:

附加信息:尝试在受保护的内存中读取或写入。这通常表明有其他内存损坏。

我做错了什么?? 感谢您的宝贵时间。

【问题讨论】:

  • 您的标题显示为C++,但您的问题和标签显示为c。是哪个?
  • 你可能没有做错什么。如果 dll 中存在访问应用程序分配内存之外的内存的错误,则可能会出现异常。
  • long 是 32 位的,所以 C# 中的 int
  • 对不起艾米,是一个 C++。我编辑。
  • 我已经为 int 交易了多头,并将“CallingConvention.Cdecl”更改为“CallingConvention.Stdcall”,它成功了!!!

标签: c# c struct marshalling dllimport


【解决方案1】:

CallingConvention = CallingConvention.Cdecl 是个问题。 C 函数 typedef 是:

typedef void (WINAPI *TPROC_PAY_VENTA)(long Importe, bool ProcessMessages, TResultado *Resultado);

WINAPI 表示stdcall。将DllImport 行上的调用约定更改为CallingConvention.Stdcall

这里发生内存冲突错误绝对是有道理的;如果 C# 代码认为调用约定是cdecl,它将向堆栈指针添加几个字节,这会使堆栈不平衡。

【讨论】:

  • 我改变了,它的工作!但我有一个新问题。该结构不接收数据,它混淆了它,我不知道为什么。
  • 内存冲突实际上是由long参数引起的,在C#声明中必须是int。在 32 位模式下,它会导致指针被传递到错误的堆栈位置。最后一个参数需要 [Out],因此结构体在调用后被复制回来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多