- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个 C++ 类,它有一个标题(matrixheader.h)这样:
#pragma once
class M
{
public:
M(int m,int n);
void MSet(int m,int n,double d);
double MGet(int m,int n);
~M();
private:
double** mat;
};
类在(matrixbody.cpp)中定义如下:它是在Win32平台上构建的。
#pragma once
#include "matrixhead.h"
M::M(int m,int n)
{
mat = new double*[m];
for (int i = 0; i < m; i++)
{
mat[i] = new double[n];
}
}
void M::MSet(int m,int n,double d)
{
mat[m][n] = d;
}
double M::MGet(int m,int n)
{
double d = mat[m][n];
return d;
}
M::~M()
{
delete[] mat;
}
我已经为类做了一个包装器(matrixwrapper.cpp):包装器也是在 Win32 平台中构建的。
#include "matrixhead.h"
#include "matrixbody.cpp"
extern "C" __declspec(dllexport) void* Make(int m,int n)
{
M o(m,n);
return &o;
}
extern "C" __declspec(dllexport) void setData(void* mp,int m,int n,double d)
{
M* ap = (M*)mp;
M a = *ap;
a.MSet(m,n,d);
}
extern "C" __declspec(dllexport) double getData(void* mp,int m,int n)
{
M* bp = (M*)mp;
M b = *bp;
double d = b.MGet(m,n);
return d;
}
我将类导入到 C# 并尝试从 C# 调用 C++ dl 方法:
using System;
using System.Runtime.InteropServices;
namespace wrappertest
{
class Program
{
[DllImport("matrixwrapper.dll")]
unsafe public static extern void* Make(int m,int n);
[DllImport("matrixwrapper.dll")]
unsafe public static extern void setData(void* mp,int m, int n,double d);
[DllImport("matrixwrapper.dll")]
unsafe public static extern double getData(void* mp,int m, int n);
static unsafe void Main(string[] args)
{
void* p = Make(10, 10);
setData(p,10,1,10);
Console.WriteLine(getData(p,10,1));
}
}
}
但是当我尝试从 C# 运行 C++ dll 方法时,出现以下错误
1//试图读取或写入 protected 内存。这通常表示在 x64 中运行 C# 代码时其他内存已损坏。
2//在x86 Active/x86或AnyCPU平台上运行时,试图加载格式不正确的程序。
问题:
1//上面的代码有什么问题?
2//考虑到我的最终目标是在 C++ 中创建一个 2d 动态数组并在数组中读取/写入数据,例如上面 matrixheader.h 文件中的一个 double**mat 从 C# 中?还有其他的吗实现方式?
最佳答案
让我们先从简单的事情开始:
An attempt was made to load a program with incorrect format when runnning in x86 Active/x86 or in AnyCPU platform.
这仅表示您的平台不匹配。您要么尝试在 x64 .NET 运行时加载 x86 C++ dll,要么相反。
下面的错误才是真正的问题:
Attempted to read or write protected memory.This is often an indication that other memory is corrupt when running C# code in x64.
这是意料之中的,因为您的 Make
函数在堆栈上创建一个对象,然后返回指向它的指针。当您读回此对象时,堆栈上的内容已更改(堆栈正在被重用),并且 mat
指针指向其他地方,很可能指向未分配的内存。
请see this answer我在其中更深入地了解了这个问题(它是 C#,但它是同一个问题)。
你必须分配一些动态内存来解决你的问题。你可以试试:
extern "C" __declspec(dllexport) void* Make(int m,int n)
{
M* o = new M(m,n);
return o;
}
当然,如果您不想泄漏内存,则必须再创建一个方法来执行匹配的delete
。
此外,正如 Mgetz 在评论中指出的那样,M
类本身存在内存泄漏。析构函数中的 delete[] mat;
调用不会释放每个已分配的内存块。您在构造函数中调用 new
m + 1
次,这意味着您必须调用 delete[]
m + 1
次也在析构函数中,每个 new
一次。您可能应该将 m
和 n
保留为您的类中的字段(至少 m
是强制性的,以了解对 delete[ 的调用次数]
你必须做的)。
更好的解决方案是使用单个数组而不是交错数组。您将该数组中的索引 i, j
计算为 i * m + j
。您也可以使用 std::vector
或完全在 C# 中完成:
public class M
{
private double[] _items;
private int _m;
private int _n;
public M(int m, int n)
{
_items = new double[m * n];
_m = m;
_n = n;
}
public this[int i, int j]
{
// Here, you should perform a bounds check on i and j against _m and _n
get { return _items[i * _m + j]; }
set { _items[i * _m + j] = value; }
}
}
关于c# - 在 C# 中读写 C++ 动态数组 (InteropServices),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27963825/
我目前正在将Windows 8.1应用程序移植到Windows 10 UAP应用程序,该应用程序使用互操作在C++和C#之间进行通信,并且 pop 以下错误: $(ProjectName).Inter
我第一次使用可选参数,但我无法理解这两个方法定义之间的区别: private void method1([Optional, DefaultParameterValue(string.Empty)]
我有一个Windows Forms应用程序,该应用程序已发布并安装在服务器上,但是当我尝试使用它时,可悲的是出现了此错误: ************** Exception Text ********
我们有一个连接到显微镜的WPF应用程序。 在一种情况下,在应用程序中我们可以切换显微镜的物镜,并且当我们这样做时,会有一个硬件调用告诉显微镜更换透镜,然后更新UI。 我们在这种情况下进行了压力测试,最
当我在我们的构建服务器上运行 WatiN 测试时,它们都会抛出这个 InteropServices.COMException: MyTestClassName.MyTestMethodName: Sy
Microsoft.Office.Interop.Excel.WorkbookClass.SaveAs()方法在 Windows server 2003 和 XP 上运行良好,但在 Windows s
我已经搜索过这个,但我找不到任何关于这个错误的具体信息或如何解决它。 我们在代码中不同位置的不同计算机上间歇性地收到此错误。 这里是错误: 计算机 1: Application: propane.ex
请看下面的代码 声明 vector> *contours; vector> *contoursPoly; contours = new vector>(); contoursPoly = new ve
我有一个包含 2 页 calendar.xaml(起始页)和 historystatistics.xaml 的应用程序。当我导航到 historystatistics 并返回到日历然后尝试通过下拉手势
我们使用 MongoDB 的每个项目都会有一个问题,即无法加载 System.Runtime.InteropServices 库。 这次的错误很有意思: 外部异常找不到lib的4.3.0.0版本。但是
每当我尝试使用应用程序洞察和 Entity Framework 运行 webjob 项目时,我都会收到此错误。 System.IO.FileLoadException: 'Could not load
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 4 年前。 Improve
当我尝试在目标机器上部署我的应用程序时出现此错误。 我用谷歌搜索,发现一些 dll 需要注册(在我的应用程序中使用) 所以,我将 dll 复制到 System32 并执行了 regsvr32 然后我得
我正在尝试制作一个通用应用程序,它只打开一个文件夹(如快捷方式)但允许使用自定义颜色和更大图标的新开始磁贴设计。 当我打开 FolderPicker 以授予应用程序访问目录的权限时,出现错误,我不知道
我有以下代码: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Inte
在我的 Microsoft Surface 项目中,我总是遇到很多以下异常: 'MuReSe.vshost.exe' (Managed (v2.0.50727)): Loaded 'C:\Window
我正在尝试使用 Swig 来包装 Raknet 以便与 Unity 一起使用,但我无法构建生成的 C# 文件,因为我有 2,300 多个错误,其中说: The type or namespace na
我有一个使用Microsoft Interop Services与Access对话的ASP.NET应用程序。 更改IIS服务器,现在在调用时出现异常: oAccess.DoCmd.OutputTo (
我正在运行WMI查询,但是在运行任何查询之前,我需要一种方法来测试连接是否正常工作。 下面是我创建的用于在运行任何查询之前测试连接的方法。 关于如何测试连接失败的任何想法? priv
我一直收到这个错误: System.Runtime.InteropServices.COMException was thrown on "C:\Users\---\documents\visual
我是一名优秀的程序员,十分优秀!