C++调用dll函数时发生访问冲突

发布于 2024-08-24 16:36:35 字数 654 浏览 6 评论 0原文

我的 VC++ Win32 DLL 中有一个函数定义,

DEMO2_API void ProcessData(char* i_buff, unsigned short i_len, char* o_buf,
unsigned *o_len, unsigned short *errorCode)
{
    __describe (i_buff,&i_len,o_buf,o_len,errorCode);
}

该 dll 函数由 ac# 应用程序调用。 调用时,它会生成访问冲突异常。

经过研究,我发现了我的问题的原因。

http://social. msdn.microsoft.com/Forums/en-US/csharplanguage/thread/6e843243-baf4-4eb1-8a20-c691ad47762c

但无法理解他们在示例代码中到底在做什么。 有人能给我解释一下吗?

外部分配内存后,C# 中的 P/Invoke 签名是什么?

I have a function definition in my VC++ Win32 DLL

DEMO2_API void ProcessData(char* i_buff, unsigned short i_len, char* o_buf,
unsigned *o_len, unsigned short *errorCode)
{
    __describe (i_buff,&i_len,o_buf,o_len,errorCode);
}

This dll function is called by a c# application.
When called, it generate access violation exception.

After reasearching i found, the cause for my problem.

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/6e843243-baf4-4eb1-8a20-c691ad47762c

But could not understand what exactly they are doinng in example code.
Can someone explain it so me?

And what would be P/Invoke signature in c# after externally allocating memory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肥爪爪 2024-08-31 16:36:35

C# 使用 IntPtr 来表示外部分配的内存。 C# 指针和引用只能与垃圾收集器提供的内存一起使用。

System.InteropServices.Marshal 类提供了一些与 IntPtr 表示的本机内存区域进行交互的方法,当然它们不是类型安全的。

但我在你的函数中没有看到任何可以返回指向已分配内存的指针的内容。您需要一个双指针参数或一个指针返回值,但两者都没有。

编辑以根据要求添加示例:

// this doesn't work right
void external_alloc_and_fill(int n, int* result)
{
  result = new int[n];
  while (n-- > 0) { result[n] = n; }
}

extern external_alloc_and_fill(int n, int* result)
int a = 5;
fixed (int* p = &a) {
  external_alloc_and_fill(17, p);
  // p still points to a, a is still 5
}

更好:

// works fine
void external_alloc_and_fill2(int n, int** presult)
{
  int* result = *presult = new int[n];
  while (n-- > 0) { result[n] = n; }
}

extern external_alloc_and_fill2(int n, ref IntPtr result)
int a 5;
IntPtr p = &a;
external_alloc_and_fill2(17, ref p);
// a is still 5 but p is now pointing to the memory created by 'new'
// you'll have to use Marshal.Copy to read it though

C# uses IntPtr to represent externally allocated memory. C# pointers and references can only be used with memory provided by the garbage collector.

The System.InteropServices.Marshal class provides some methods for interacting with native memory areas represented by IntPtr, of course they aren't typesafe.

But I don't see anything in your function that could return a pointer to allocated memory. You'd need a double-pointer argument, or a pointer return value, and you have neither.

EDIT to add example as requested:

// this doesn't work right
void external_alloc_and_fill(int n, int* result)
{
  result = new int[n];
  while (n-- > 0) { result[n] = n; }
}

extern external_alloc_and_fill(int n, int* result)
int a = 5;
fixed (int* p = &a) {
  external_alloc_and_fill(17, p);
  // p still points to a, a is still 5
}

better:

// works fine
void external_alloc_and_fill2(int n, int** presult)
{
  int* result = *presult = new int[n];
  while (n-- > 0) { result[n] = n; }
}

extern external_alloc_and_fill2(int n, ref IntPtr result)
int a 5;
IntPtr p = &a;
external_alloc_and_fill2(17, ref p);
// a is still 5 but p is now pointing to the memory created by 'new'
// you'll have to use Marshal.Copy to read it though
装纯掩盖桑 2024-08-31 16:36:35

我将 O_len 的传递模式更改为 out 而不是 ref 并且它有效。

感谢大家给出很好的答案和评论。我希望这对其他社区成员有用(加上那些谷歌搜索......)

I changed passing mode of O_len to out instead of ref and it works.

Thnaks everyone for giving nice answers and comments. I hope this would be useful for other community members ( plus those googling...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文