我正在尝试在zabbix_sender
程序中使用c#
函数。这是我的c#
代码:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct zabbix_sender_value_t
{
[MarshalAs(UnmanagedType.LPStr)] public String host;
[MarshalAs(UnmanagedType.LPStr)] public String key;
[MarshalAs(UnmanagedType.LPStr)] public String value;
}
[DllImport("zabbix_sender.dll", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int zabbix_sender_send_values(
[param: MarshalAs(UnmanagedType.LPStr)] String address,
[param: MarshalAs(UnmanagedType.U2)] ushort port,
[param: MarshalAs(UnmanagedType.LPStr)] String source,
[param: MarshalAs(UnmanagedType.Struct)] zabbix_sender_value_t values,
[param: MarshalAs(UnmanagedType.U4)] int count,
[param: MarshalAs(UnmanagedType.LPStr)] String result
);
static void Main()
{
zabbix_sender_value_t values;
values.host = "some_hostname";
values.key = "agent.version";
values.value = "2.0.0";
string res = "";
zabbix_sender_send_values("172.16.1.1", 10051, "127.0.0.1", values, 1, res);
}
这是C函数的定义,我试图从DLL调用:
int zabbix_sender_send_values(
const char *address,
unsigned short port,
const char *source,
const zabbix_sender_value_t *values,
int count,
char **result);
typedef struct
{
char *host;
char *key;
char *value;
}
zabbix_sender_value_t;
执行我的C#代码以“尝试读取或写入受保护的内存”结束异常。这通常表明其他内存已损坏。
我使用编组参数玩了很多但没有运气。
这是我第一次使用DLL
程序使用原生c#
代码,我真的不知道我现在要做什么。
请任何帮助,意见,踢到哪里找出线索?
由于
答案 0 :(得分:0)
Just an off-the-cuff guess but did you enable "allow unsafe code" in your project properties and trying wrapping the call in an unsafe { } clause?
答案 1 :(得分:0)
当您发送ByVal字符串作为此参数时,函数接受char**
作为结果(最后一个)参数。字符串对象wwill marshal为char*
所以你应该将它声明为ref IntPtr
或out string
(在这种情况下推荐)将字符串指针发送到函数。
但主要问题是因为您发送ByVal zabbix_sender_value_t
作为values
参数,而函数接受此结构的数组。如果只想发送一个实例,可以将其声明为数组或ref
参数。
答案 2 :(得分:0)
非常感谢你所有的消遣。
我试过这个
\tmp
并调用这样的函数:
[DllImport("zabbix_sender.dll", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int zabbix_sender_send_values(
[param: MarshalAs(UnmanagedType.LPStr)] String address,
[param: MarshalAs(UnmanagedType.U2)] ushort port,
[param: MarshalAs(UnmanagedType.LPStr)] String source,
ref zabbix_sender_value_t values,
[param: MarshalAs(UnmanagedType.U4)] int count,
out IntPtr result
);
它可以工作,但如果我尝试在调试模式下运行,则抛出异常PInvokeStackImbalance。它不适合在生产中使用,不是吗?
谢谢
答案 3 :(得分:0)
Well, thank You again. I finish with this code without any exception even in Debug mode. The problem with exception appeared only when i try build program in x86 platform. When i use x64 or AnyCPU ( 64 bit DLL ), everything works well. Maybe misconfiguration?
Here is my final code:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct zabbix_sender_value_t
{
[MarshalAs(UnmanagedType.LPStr)] public string host;
[MarshalAs(UnmanagedType.LPStr)] public string key;
[MarshalAs(UnmanagedType.LPStr)] public string value;
}
[DllImport("zabbix_sender.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int zabbix_sender_send_values(
[param: MarshalAs(UnmanagedType.LPStr)] string address,
[param: MarshalAs(UnmanagedType.U4)] int port,
[param: MarshalAs(UnmanagedType.LPStr)] string source,
[param: MarshalAs(UnmanagedType.Struct)] ref zabbix_sender_value_t values,
[param: MarshalAs(UnmanagedType.U4)] int count,
out IntPtr result
);
static void Main()
{
zabbix_sender_value_t values;
values.host = "some_hostname";
values.key = "zbx.trap";
values.value = "99";
IntPtr res ;
unsafe {
try
{
zabbix_sender_send_values("10.0.236.1", 10051, "10.0.236.12", ref values, 1, out res);
string output = Marshal.PtrToStringAnsi(res);
Console.WriteLine(output);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}