参数中的数据值被复制到其他参数 c++, c#

Posted

技术标签:

【中文标题】参数中的数据值被复制到其他参数 c++, c#【英文标题】:Data values in the parameters are beeing copied to the other parameters c++, c# 【发布时间】:2012-06-04 13:35:08 【问题描述】:

在 c++ 中,我要导出的方法是:

__declspec(dllexport) int __thiscall A::check(char *x,char *y,char *z)

  temp=new B(x,y,z);

在 c# 中我像这样导入这个方法:

[DllImport("IDLL.dll", CallingConvention=CallingConvention.ThisCall, ExactSpelling = true, EntryPoint = "check")]
    public static extern int check(string x, string y, string z);

我在 c# 中像这样调用这个方法并传递值:

public int temp()

  string x="sdf";
  string y="dfggh";
  string z="vbnfg";
  int t;

  t=Class1.check(x,y,z);
  return t;

问题是,当我调试本机代码时,我看到参数 x、y、z 的值为 sdf、dfggh、vbnfg,并且在它们到达 c++ dll 时甚至在它进入本机 c++ 之前就被更改了dll方法。

x=dfggh,y=vbnfg,z=null value

并且给我一个错误,说空指针值被传递给函数。谁能帮我解决这个奇怪的问题。

【问题讨论】:

刚刚看过我几年前写的一些代码。尝试在每个 string 参数之前添加 [MarshalAs(UnmanagedType.LPStr)]UnmanagedType.LPStr 表示 指向以空字符结尾的 ANSI 字符数组的指针 是不是只有z变成了null,x和y都没有问题?如果是,则检查 B 的 ctor 中修改 z 的那些部分。 @kol --- 甚至在进入构造函数 B 本身之前,值正在被更改。 @hmjd ---我尝试了你提到的但有同样的问题。 【参考方案1】:

看起来您的本机方法是一个实例(与静态)方法。我猜你的第一个参数会以某种方式映射到“this”。

这是一个例子:

#include <fstream>
using namespace std;

class A

public:
__declspec(dllexport) static int __stdcall check(char *x,char *y,char *z)

    ofstream f;
    f.open("c:\\temp\\test.txt");
    f<<x<<endl;
    f<<y<<endl;
    f<<z<<endl;
    return 0;

    

__declspec(dllexport) int __thiscall checkInst(char *x,char *y,char *z)

    ofstream f;
    f.open("c:\\temp\\testInst.txt");
    f<<x<<endl;
    f<<y<<endl;
    f<<z<<endl;
    return 0;

    
;

看到第一个的static关键字了吗?

Imports(因为我很懒,所以我用了乱七八糟的名字):

[DllImport("TestDLL.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true, EntryPoint = "?check@A@@SGHPAD00@Z")]
    public static extern int check(string x, string y, string z);

    [DllImport("TestDLL.dll", CallingConvention = CallingConvention.ThisCall, ExactSpelling = true, EntryPoint = "?checkInst@A@@QAEHPAD00@Z")]
    public static extern int checkInst(IntPtr theObject, string x, string y, string z);

这使它像这样工作:

check("x", "yy", "zzz");

实例方法需要一个 IntPtr

IntPtr obj = IntPtr.Zero;
checkInst(obj, "1", "12", "123");

而我的 test.txt 的内容是:

x
yy
zzz

和 testInst.txt

1
12
123

【讨论】:

“本机方法是实例(相对于静态)方法”是什么意思 A::check 看起来像是 A 类上的非静态(需要对象)方法,您需要导出静态方法或函数才能使 P/Invoke 工作 我认为不需要静态方法才能使用 pinvoke。因此,由于该方法是 __stdcall 类型,所以它需要是静态的? 检查这个答案***.com/a/2354222/842543 您不能只从 C# 静态调用一个方法 - 它需要另一端的对象?谁来建造它? 好的,我在这里感到困惑,您能否提供一个示例代码来说明您的观点。基本示例就足够了。

以上是关于参数中的数据值被复制到其他参数 c++, c#的主要内容,如果未能解决你的问题,请参考以下文章

C#中Listview的数据复制到另外一个Listview的问题

如何在 C# 9 中复制/克隆记录?

参数或参数? [复制]

参数或参数? [复制]

第5章-方法

如何将命令参数中的引号转义到 sh -c? [复制]