我需要从C DLL导出函数。这是我写的例子
typedef struct tag_struct {
unsigned char first;
unsigned char second;
} st_struct;
__declspec(dllexport) unsigned char Func( st_struct *ptr )
{
return ptr->first + ptr->second;
}
以下是我用于导入上述功能的C#代码。
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ImportTest
{
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public class st_struct
{
public byte first;
public byte second;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
st_struct x = new st_struct();
x.first = 1;
x.second = 2;
byte result = Func(ref x);
}
[DllImport("MarshalTest.dll")]
protected static extern byte Func(ref st_struct inputs);
}
}
我的问题是Func的返回值不是3,因为它应该是(1 + 2)。
我正在使用调试器来查看DLL中的值 - 它们是不同的(不是我提供的1和2)。
函数返回正确的值,我改变了C#代码:
public Form1()
{
InitializeComponent();
st_struct x = new st_struct();
x.first = 1;
x.second = 2;
byte result = Func(x);
}
[DllImport("MarshalTest.dll")]
protected static extern byte Func(st_struct inputs);
删除ref时问题消失了。但我不明白为什么。
你可以解释一下吗?
答案 0 :(得分:2)
您可能认为passing parameter by reference
需要st_struct
关键字才能ref
。但由于st_struct
被定义为引用类型(类是引用类型),因此参数是通过引用传递的,而不是通过值传递的。您不需要struct
关键字。
如果ref
被定义为server {
auth_basic "closed site";
auth_basic_user_file /tmp/.htpasswd.txt;
listen 81 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/path/to/root
index index.html index.htm;
server_name ipaddress;
,您可能会在使用<?php
require_once('config.php');
$posts = array();
/* require the user as the parameter */
if(isset($_GET['roll']) and isset($_GET['name']))
{
/* soak in the passed variable or set our own */
$roll = $_GET['roll']; //no default
$name = $_GET['name']; //no default
/* grab the posts from the db */
if($roll!="" and $name!="")
{
$query = "INSERT INTO STUDENT VALUES('$roll','$name')";
if(mysql_query($query,$dblink))
{
$posts[] = array('status'=>'Data Inserted');
}
else
{
$posts[] = array('status'=>'Not Inserted');
}
}
else
{
$posts[] = array('status'=>'Null Value sent');
}
/* disconnect from the db */
@mysql_close($db);
}
else
{
$posts[] = array('status'=>'Please check the arguments');
}
/* output in necessary format */
header('Content-type: application/json');
echo json_encode(array('posts'=>$posts));
?>
关键字时发现它有用。
答案 1 :(得分:1)
正如@kennyzx所提到的,由于你的st_struct
是一个类,它已经是一个引用类型,并将作为指针传递。我怀疑抛出ref
会给你一个双指针,这在混合托管和非托管代码时没有多大意义。如果指针发生变化,编组可以处理它并为你创建一个新对象,但这似乎是一件粗略的事情。
因此,当传递没有ref
的类时,它按预期工作(C代码获取指针)。如果将其更改为struct
,则在没有ref
的情况下传递它应该将其传递到堆栈并使用ref
传递它将其作为指针传递。
在你的情况下使用struct
似乎是明显的选择,因为它可以直接传递(CLR只需要固定它并传递一个指针)。使用class
我怀疑会涉及更多的编组。