- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试实现一些涉及在托管 C# 和非托管 C++ 代码之间编码数组的项目。我遇到了一个问题,我在网上找到的解决方案似乎都不起作用。对于这方面的任何评论,我将不胜感激。
我没有展示完整的代码,而是展示问题的非常简化的部分。虽然它看起来像一个大块——它很简单——只是概念性的。只是想提供尽可能多的全貌。
C++部分:
Object.h
class cObject
{
public:
//...constructor, destructor...
int Method_Known_Size(double* array, int size);
int Method_Unknown_Size(double* array);
...
void FreeArray(double* p);
}
对象.cpp
int Method_Known_Size(double* array, int size)
{
//modify array somehow..
for(int i=0; i<size; i++) array[i] = i;
}
int method_Unknown_Size(double* array)
{
int size = 9;
array = new double[size];
for(int i=0; i<size; i++) array[i] = i;
}
(跳过 Caller.h)Caller.cpp
//...callers for constructor, destructor, for releasing unmanaged memory...
extern "C" int __stdcall Run_Known_Size(cObject* pObject, double* array, int size)
{
return cObject->Method_Known_Size(array, size);
}
extern "C" int __stdcall Run_Unknown_Size(cObject* pObject, double* array)
{
return cObject->Method_Unknown_Size(array);
}
extern "C" void __stdcall Release(cObject* cObject, double* array)
{
if(cObject != NULL) cObject->FreeArray(array);
}
所以,基本上 Run_Known_Size
方法只是修改已经由 C# 分配的内存,而 Run_Unknown_Size
创建数组并修改它。
C#部分
public class DllWrapper: IDisposable
{
/* Creating an object, disposing,...
[DllImport("cObject.dll")]
CreateObject();...DisposeObject(IntPtr pObject);
...CallFreeArray(IntPtr pArray);*/
[DllImport("cObject.dll")]
private static extern int CallRun_Known_Size(IntPtr pObject,
[Out] double [] arr_allocated, int size);
[DllImport("cObject.dll")]
private static extern int CallRun_Unknown_Size(IntPtr pObject,
[Out] IntPtr arr_not_allocated);
private IntPtr m_pNativeObject;
public DllWrapper()
{
this.m_pNativeObject = CreateObject();
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool bDisposing)
{
if (this.m_pNativeObject != IntPtr.Zero)
{
DisposeObject(this.m_pNativeObject);
this.m_pNativeObject = IntPtr.Zero;
}
if (bDisposing)
{
GC.SuppressFinalize(this);
}
}
~DllWrapper()
{
Dispose(false);
}
public void ReleaseUnmanAraray(IntPtr pArr)
{
CallFreeArray(pArr);
}
public int Run_Known_Size(double[] arr_allocated, int size)
{
return CallRun_Known_Size(this.m_pNativeObject, arr_allocated, size);
}
public int Run_Unknown_Size(IntPtr arr_not_allocated)
{
return CallRun_Known_Size(this.m_pNativeObject, arr_not_allocated);
}
}
static void Main(string[] args)
{
double[] alloc_arr = new double[] { 1, 5, 3, 3, 5, 5, 8, 9,1 };
int size = 9;
double[] Arr_for_Copy = new double[size];
IntPtr pArr = new IntPtr();
DllWrapper wrapper = new DllWrapper();
int res1 = Run_Known_Size(alloc_arr, size);
int res2 = Run_Unknown_size(pArr);
if (pArr != IntPtr.Zero) // pArr IS ZERO ALWAYS!!!!!!
{
Marshal.Copy(pArr, Arr_for_Copy, 0, size);
}
else
{
Console.WriteLine("Pointer was zero again");
}
wrapper.ReleaseUnmanAraray(pScores);
wrapper.Dispose();
Console.ReadLine();
}
对于在 C# 中分配的数组,一切都工作得很好——它们是从 C++ 修改而来的,没有错误。但是如果我不知道数组的大小,因此无法预分配数组,我找到的唯一解决方案是传递 [Out] IntPtr 并让 C++ 管理内存、分配和修改数组。然后返回的 IntPtr 可以编码到 C# 的 double[] 数组,因为我们已经知道大小(为简化起见,我只将数字 4 作为大小,但我通过 int* size 来确定大小)。
在传递 IntPtr 并基于此指针在 C++ 中创建数组后,我的所有试验都以零指针结束(没有错误)。
我见过涉及 COM 对象的解决方案,但由于可移植性问题,我不得不避免使用它。
提前致谢。
最佳答案
Method_Unknown_Size
的参数是 double*
并且您正在更改参数本身。如果你想改变调用者发送的原始值,你应该将参数定义为一个指向数组的指针,这意味着指向double的指针或引用指向 double 的指针
您还应该以某种方式告诉调用者数组的大小(我想您已经做到了)。
C++:
int method_Unknown_Size(double *&array)
{
int size = 9;
array = new double[size];
for(int i=0; i<size; i++) array[i] = i;
return size;
}
void FreeArray(double *&p)
{
delete[] p;
p = NULL;
}
extern "C" int __stdcall Run_Unknown_Size(cObject *pObject, double *&array)
{
return cObject->Method_Unknown_Size(array);
}
extern "C" void __stdcall Release(cObject *cObject, double *&array)
{
if(cObject != NULL) cObject->FreeArray(array);
}
C#:
[DllImport("cObject.dll")]
private static extern int Run_Unknown_Size(IntPtr pObject,
out IntPtr arr_not_allocated);
[DllImport("cObject.dll")]
private static extern int Release(IntPtr pObject,
ref IntPtr arr_not_allocated);
// to allocate the array:
IntPtr pArr;
int res2 = Run_Unknown_size(m_pNativeObject, out pArr);
// to free the array:
Release(m_pNativeObject, ref pArr);
这绝对有效!如果没有,请告诉我!
关于c# - 在 C# 中传递 IntPtr 指针后,在非托管 C++ 代码中分配数组,编码(marshal)处理类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15217939/
我有一个应用程序,它会抛出 GKSession 并在各种条件下(连接超时、 session 失败等)创建一个新的 GKSession。不过,我遇到了内存泄漏问题,并且有时会在重新连接几次循环后崩溃。
比如我在宿主代码中有一个浮点指针 float *p 是否可以确定他指向的内存类型(设备/主机)? 最佳答案 在 UVA system 中, 运行时 API 函数 cudaPointerGetAttri
我已将项目转换为 .Net 4.0 并且以下代码不起作用: typeof(RuntimeTypeHandle).GetMethod("Allocate", BindingFlags.Instance
当我声明 char ch = 'ab' 时,ch 只包含 'b',为什么它不存储 'a'? #include int main() { char ch = 'ab'; printf("%c"
我对 Disk Sector 和 Block 有疑问。扇区是一个单位,通常为 512 字节或 1k、2k、4k 等取决于硬件。文件系统 block 大小是一组扇区大小。 假设我正在存储一个 5KB 的
假设我有 8 个人和5000 个苹果。 我想将所有苹果分发给所有 8 个人,这样我就没有苹果了。 但每个人都应该得到不同数量 将它们全部分发出去的最佳方式是什么? 我是这样开始的: let peopl
我正在构建的网站顶部有一个搜索栏。与 Trello 或 Gmail 类似,我希望当用户按下“/”键时,他们的焦点就会转到该搜索框。 我的 JavaScript 看起来像这样: document.onk
我有一小段代码: if (PZ_APP.dom.isAnyDomElement($textInputs)){ $textInputs.on("focus", function(){
我观察到以下行为。 接受了两个属性变量。 @property (nonatomic, retain) NSString *stringOne; @property (nonatomic, assign
我正在解决这样的问题 - 实现一个计算由以下内容组成的表达式的函数以下操作数:“(”、“)”、“+”、“-”、“*”、“/”。中的每个数字表达式可能很大(与由字符串表示的一样大)1000 位)。 “/
我有一组主机和一组任务。 每个主机都有 cpu、mem 和任务容量,每个任务都有 cpu、mem 要求。 每个主机都属于一个延迟类别,并且可以与具有特定延迟值的其他主机通信。 每个任务可能需要以等于或
该程序的作用:从文件中读取一个包含 nrRows 行和 nrColomns 列的矩阵(二维数组)。矩阵的所有元素都是 [0,100) 之间的整数。程序必须重新排列矩阵内的所有元素,使每个元素等于其所在
世界!我有个问题。今天我尝试创建一个代码,它可以找到加泰罗尼亚语号码。但是在我的程序中可以是长数字。我找到了分子和分母。但我不能分割长数字!此外,只有标准库必须在此程序中使用。请帮帮我。这是我的代码
我确定我遗漏了一些明显的东西,但我想在 Objective C 中创建一个 NSInteger 指针的实例。 -(NSInteger*) getIntegerPointer{ NSInteger
这个问题在这里已经有了答案: Difference between self.ivar and ivar? (4 个答案) 关闭 9 年前。
我如何将 v[i] 分配给一系列整数(v 的类型是 vector )而无需最初填充 最佳答案 你的意思是将 std::vector 初始化为一系列整数? int i[] = {1, 2, 3, 4,
我想寻求分配方面的帮助....我把这个作业带到了学校......我必须编写程序来加载一个 G 矩阵和第二个 G 矩阵,并搜索第二个 G 矩阵以获取存在数第一个 G 矩阵的......但是,当我尝试运行
我必须管理资源。它基本上是一个唯一的编号,用于标识交换机中的第 2 层连接。可以有 16k 个这样的连接,因此每次用户希望配置连接时,他/她都需要分配一个唯一索引。同样,当用户希望删除连接时,资源(号
是否有任何通用的命名约定来区分已分配和未分配的字符串?我正在寻找的是希望类似于 us/s 来自 Making Wrong Code Look Wrong ,但我宁愿使用常见的东西也不愿自己动手。 最佳
我需要读取一个 .txt 文件并将文件中的每个单词分配到一个结构中,该结构从结构 vector 指向。我将在下面更好地解释。 感谢您的帮助。 我的程序只分配文件的第一个字... 我知道问题出在函数 i
我是一名优秀的程序员,十分优秀!