导入C 功能将结构的指针返回到VB.NET中
Import C++ function returning pointer of structs into VB.NET
我已经在C 中创建了一个简单的DLL,其唯一目的是隔离问题并在小规模上测试,导入一个函数,该函数返回与不同类型成员的结构列表。
dll_header.h
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif
enum color_type
{
RGB = 1,
MONO = 2
};
struct my_struct
{
unsigned char *name;
char *value;
color_type type;
my_struct* next;
};
extern "C" struct my_struct MY_DLL_API * get_list(void);
dll_header.cpp
#include "dll_header.h"
MY_DLL_API my_struct * get_list(void)
{
my_struct my_list[2];
unsigned char name1[] = "name1";
unsigned char name2[] = "name2";
char val1[] = "val1";
char val2[] = "val2";
my_list[0].name = name1;
my_list[0].value = val1;
my_list[0].type = RGB;
my_list[0].next = &my_list[1];
my_list[0].name = name2;
my_list[0].value = val2;
my_list[0].type = MONO;
my_list[0].next = NULL;
return my_list;
}
就像我说的那样,我必须使用这些数据类型(不能将它们更改为字符串或其他任何东西,因为我正在测试某些东西,并且需要这样的东西)
)现在,在我的vb.net应用程序中,我导入并尝试从dll
检索这样的列表form1.vb
Imports System.Runtime.InteropServices
Imports System.Text
Public Class Form1
Public Enum color_type
RGB = 1
COLOR = 2
End Enum
Private Structure my_struct
Public name As Byte()
Public value As Char()
Public type As color_type
Public next As IntPtr
End Structure
Private Declare Function get_list Lib "my_lib.dll" () As IntPtr
Private my_list As List(Of my_struct)
Private Sub get_list()
Dim my_list_pointer As IntPtr = get_list()
my_list = New List(Of my_struct)
Dim my_item As my_struct
While my_list_pointer <> IntPtr.Zero
my_item = CType(Marshal.PtrToStructure(my_list_pointer, GetType(my_struct)), my_struct)
my_list.Add(my_item)
my_list_pointer = my_item.next
End While
End Sub
我尝试了许多其他方法,这些方法特殊更改了数据类型,但是到目前为止,我在尝试运行代码时坚持使用此例外:
system.AccessviolationException:'试图读取或写下受保护的 记忆。这通常表明其他记忆是损坏的。'
试图找到一种使这两个人相互理解的方法
要么使用混合模式C 在本机和托管类型之间进行翻译,要么使用与p/indoke兼容的类型。
查看Win32如何定义结构(以及使用这些功能)是一个良好的开始,可以帮助您了解如何将兼容结构定义为P/Invoke的主要目的之一,即能够使用托管代码中的Win32 API。
如果您选择混合模式,则可以在世界两者之间进行任何必要的翻译,因为您可以在同一组件中混合本机C 和C /CLI。因此,从本质上讲,您将编写将本机结构转换为托管结构的代码,然后VB.NET可以使用该托管代码(假设您使用vb.net中可用的类型)。
好吧,如果您选择混合模式路线,则通常会以3个dll/zhoundberies/operutable最终结束,因为您将拥有原始的C DLL(本机代码),VB.NET代码(托管)和混合模式C 组装之间。
update
虽然仅读取列表,但如果不是这种情况,则相对容易提供代码,但根据预期的代码的使用以及现有DLL中的可用函数,可能会更难。
起点是在C /CLI中创建ref class
。
一些类似的问题
https://bytes.com/topic/c-sharp/answers/674468-passing-link-list-list-c-dll-c-pinvoke
使用PINVOKE
从C到C#的点(X,Y,Z)的返回列表从C
的自我参考结构的Pinvoke您的代码问题
您的导出函数重新调整指向不确定行为的本地变量的指针。
附加观察
如果您的原始列表是一个数组,为什么还将其列入列表?阵列更容易元帅和使用。而且表现也更好。
定义结构时,您已经明确说明字符串的编组方式以及应使用的对齐方式。您将验证一切都是预期的。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 如何使函数返回数组?用于制作在VB.NET中使用的DLL
- dll从VC++导入到VB函数的转换从dll返回错误,因为缺少链接库
- 等效于 VB DLL 函数声明的 C# 返回并返回'Attempted to read or write protected memory'错误