C#调C++写的DLL的结构体参数问题

仙剑 2011-12-28 10:45:01
C#调C++写的DLL里的一个函数

原型是:
_DLLIMP long CALL_CONVENT VLVmcConnectVoc(
long VmcHandle,
const PVOCLINK_PARAM pVocSrv,
long* pVocHandle
);

其中结构体 VOCLINK_PARAM 的定义是

typedef struct _VOCLINK_PARAM{
TCHAR sVocIp[16];
UINT nPort;
}VOCLINK_PARAM,*PVOCLINK_PARAM;

我在C#里定义了结构体 VoiceLinkParam

[StructLayout(LayoutKind.Sequential)]
struct VoiceLinkParam
{
public byte[] voiceip;
public uint port;
}

调用如下:

VoiceLinkParam voice_link_param = new VoiceLinkParam();
string voiceip = "192.168.4.44";
voice_link_param.port = 3000;
int voc_handle = 0;
int voc_connect_result = ClassVMC.VLVmcConnectVoc(vmc_handle,ref voice_link_param, ref voc_handle);
if (voc_connect_result == VMC_ERR_SUCCESS)
{
MessageBox.Show("Connect Voice Success.");
}
else
{
MessageBox.Show("Connect Voice fail.Result=" + voc_connect_result);
}


class ClassVMC
{
[DllImport("VLVmc.dll", EntryPoint = "VLVmcConnectVoc")]
public static extern int VLVmcConnectVoc(int vmc_handle,ref VoiceLinkParam voc_param, ref int voc_handle);
}


可是程序在红色处报错:尝试读取或写入受保护的内存。这通常指示其他内存已损坏;

估计是C#结构体定义的问题,正确的结构体定义应该是怎么的呢,请高手指点!

...全文
184 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
仙剑 2011-12-28
  • 打赏
  • 举报
回复
奇怪,看不到回复呀,csdn 有bug吗
tcwushaofei 2011-12-28
  • 打赏
  • 举报
回复
你顶了我的帖子么 我也来顶顶你的 呵呵
仙剑 2011-12-28
  • 打赏
  • 举报
回复
4楼的写法我试了一下,可是程序直接奔溃了,连一个异常的消息都没有

我是在 VS2010 中用 debug 调试的

我把全部代码都贴出来吧,还请指点,谢谢!

好奇怪,为啥其他人的回复我看不到,只能看到4楼的呢?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;

namespace NetMoniterWPFApp
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private const int VMC_ERR_SUCCESS = 0;

public MainWindow()
{
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
getReturn();
}
private int GetSum(int a, int b)
{
return (a + b);
}
private void getReturn()
{
ClassVMC.VLVMC_CB vlvmc_cb = new ClassVMC.VLVMC_CB(OnVLVMCCallBack);

int vmc_handle = 0;
int lparam = 0;
int vmc_open_result = ClassVMC.VLVmcOpen(vlvmc_cb, lparam, ref vmc_handle);
if (vmc_open_result == VMC_ERR_SUCCESS)
{
VoiceLinkParam voice_link_param = new VoiceLinkParam();
voice_link_param.voiceip = "192.168.4.44";
voice_link_param.port = 3000;
int voc_handle = 0;
int voc_connect_result = ClassVMC.VLVmcConnectVoc(vmc_handle,ref voice_link_param, ref voc_handle);
if (voc_connect_result == VMC_ERR_SUCCESS)
{
MessageBox.Show("Connect Voice Success.");
}
else
{
MessageBox.Show("Connect Voice fail.Result=" + voc_connect_result);
}
}
else
{
MessageBox.Show("Open VMC fail.Result=" + vmc_open_result);
}
}
private void OnVLVMCCallBack(int voice_handle,ref VMCCB_EVT vmccb_evt, int lparam)
{
//MessageBox.Show("sjifsf");
}
}

class ClassSum
{
public delegate int d_SumAll(int a, int b);
public int SumAll(d_SumAll d_sumall)
{
return d_sumall(1, 2);
}
}
class ClassVMC
{
public delegate void VLVMC_CB(int voice_handle,ref VMCCB_EVT vmccb_evt, int lparam);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcOpen")]
public static extern int VLVmcOpen(VLVMC_CB vlvmc_cb, int lparam, ref int vmc_handle);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcClose")]
public static extern int VLVmcClose(int vmc_handle);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcConnectVoc")]
public static extern int VLVmcConnectVoc(int vmc_handle,ref VoiceLinkParam voc_param, ref int voc_handle);
}
[StructLayout(LayoutKind.Sequential)]
struct VoiceLinkParam
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string voiceip;
public uint port;
}
[StructLayout(LayoutKind.Sequential)]
struct VMCCB_EVT
{
public uint EvtCode;
public uint RetCode;
public uint Channel;
public uint BufferLen;
public IntPtr Buffer;
}
}
仙剑 2011-12-28
  • 打赏
  • 举报
回复
4楼的写法我试了一下,可是程序直接奔溃了,连一个异常的消息都没有

我是在 VS2010 中用 debug 调试的

我把全部代码都贴出来吧,还请指点,谢谢!

好奇怪,为啥其他人的回复我看不到,只能看到4楼的呢?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;

namespace NetMoniterWPFApp
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private const int VMC_ERR_SUCCESS = 0;

public MainWindow()
{
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
getReturn();
}
private int GetSum(int a, int b)
{
return (a + b);
}
private void getReturn()
{
ClassVMC.VLVMC_CB vlvmc_cb = new ClassVMC.VLVMC_CB(OnVLVMCCallBack);

int vmc_handle = 0;
int lparam = 0;
int vmc_open_result = ClassVMC.VLVmcOpen(vlvmc_cb, lparam, ref vmc_handle);
if (vmc_open_result == VMC_ERR_SUCCESS)
{
VoiceLinkParam voice_link_param = new VoiceLinkParam();
voice_link_param.voiceip = "192.168.4.44";
voice_link_param.port = 3000;
int voc_handle = 0;
int voc_connect_result = ClassVMC.VLVmcConnectVoc(vmc_handle,ref voice_link_param, ref voc_handle);
if (voc_connect_result == VMC_ERR_SUCCESS)
{
MessageBox.Show("Connect Voice Success.");
}
else
{
MessageBox.Show("Connect Voice fail.Result=" + voc_connect_result);
}
}
else
{
MessageBox.Show("Open VMC fail.Result=" + vmc_open_result);
}
}
private void OnVLVMCCallBack(int voice_handle,ref VMCCB_EVT vmccb_evt, int lparam)
{
//MessageBox.Show("sjifsf");
}
}

class ClassSum
{
public delegate int d_SumAll(int a, int b);
public int SumAll(d_SumAll d_sumall)
{
return d_sumall(1, 2);
}
}
class ClassVMC
{
public delegate void VLVMC_CB(int voice_handle,ref VMCCB_EVT vmccb_evt, int lparam);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcOpen")]
public static extern int VLVmcOpen(VLVMC_CB vlvmc_cb, int lparam, ref int vmc_handle);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcClose")]
public static extern int VLVmcClose(int vmc_handle);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcConnectVoc")]
public static extern int VLVmcConnectVoc(int vmc_handle,ref VoiceLinkParam voc_param, ref int voc_handle);
}
[StructLayout(LayoutKind.Sequential)]
struct VoiceLinkParam
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string voiceip;
public uint port;
}
[StructLayout(LayoutKind.Sequential)]
struct VMCCB_EVT
{
public uint EvtCode;
public uint RetCode;
public uint Channel;
public uint BufferLen;
public IntPtr Buffer;
}
}
仙剑 2011-12-28
  • 打赏
  • 举报
回复
4楼的写法我试了一下,可是程序直接奔溃了,连一个异常的消息都没有

我是在 VS2010 中用 debug 调试的

我把全部代码都贴出来吧,还请指点,谢谢!

好奇怪,为啥其他人的回复我看不到,只能看到4楼的呢?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;

namespace NetMoniterWPFApp
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private const int VMC_ERR_SUCCESS = 0;

public MainWindow()
{
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
getReturn();
}
private int GetSum(int a, int b)
{
return (a + b);
}
private void getReturn()
{
ClassVMC.VLVMC_CB vlvmc_cb = new ClassVMC.VLVMC_CB(OnVLVMCCallBack);

int vmc_handle = 0;
int lparam = 0;
int vmc_open_result = ClassVMC.VLVmcOpen(vlvmc_cb, lparam, ref vmc_handle);
if (vmc_open_result == VMC_ERR_SUCCESS)
{
VoiceLinkParam voice_link_param = new VoiceLinkParam();
voice_link_param.voiceip = "192.168.4.44";
voice_link_param.port = 3000;
int voc_handle = 0;
int voc_connect_result = ClassVMC.VLVmcConnectVoc(vmc_handle,ref voice_link_param, ref voc_handle);
if (voc_connect_result == VMC_ERR_SUCCESS)
{
MessageBox.Show("Connect Voice Success.");
}
else
{
MessageBox.Show("Connect Voice fail.Result=" + voc_connect_result);
}
}
else
{
MessageBox.Show("Open VMC fail.Result=" + vmc_open_result);
}
}
private void OnVLVMCCallBack(int voice_handle,ref VMCCB_EVT vmccb_evt, int lparam)
{
//MessageBox.Show("sjifsf");
}
}

class ClassSum
{
public delegate int d_SumAll(int a, int b);
public int SumAll(d_SumAll d_sumall)
{
return d_sumall(1, 2);
}
}
class ClassVMC
{
public delegate void VLVMC_CB(int voice_handle,ref VMCCB_EVT vmccb_evt, int lparam);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcOpen")]
public static extern int VLVmcOpen(VLVMC_CB vlvmc_cb, int lparam, ref int vmc_handle);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcClose")]
public static extern int VLVmcClose(int vmc_handle);
[DllImport("VLVmc.dll", EntryPoint = "VLVmcConnectVoc")]
public static extern int VLVmcConnectVoc(int vmc_handle,ref VoiceLinkParam voc_param, ref int voc_handle);
}
[StructLayout(LayoutKind.Sequential)]
struct VoiceLinkParam
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string voiceip;
public uint port;
}
[StructLayout(LayoutKind.Sequential)]
struct VMCCB_EVT
{
public uint EvtCode;
public uint RetCode;
public uint Channel;
public uint BufferLen;
public IntPtr Buffer;
}
}
sdl2005lyx 2011-12-28
  • 打赏
  • 举报
回复
正确做法:

[StructLayout(LayoutKind.Sequential)]
public struct VoiceLinkParam
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string voiceip;
public uint port;
}
tigerleq 2011-12-28
  • 打赏
  • 举报
回复
C# 到 c++ 参数 对照表
tigerleq 2011-12-28
  • 打赏
  • 举报
回复
C# 到 c++ 参数 对照表
tigerleq 2011-12-28
  • 打赏
  • 举报
回复
C# 到 c++ 参数 对照表
类型 对照
一定 要对 ,在 看看 为什么 要 那么传
sdl2005lyx 2011-12-28
  • 打赏
  • 举报
回复
结构体需要我给你的那样转换,至于为什么会“程序直接奔溃”,你可以这样确定:

你把工程属性:调试-》勾上“启用非托管代码调试”,

F11直接根据C++的代码。。。。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧