尝试将 LEPCC 从 GitHub 移植到 C# 时出现问题 - DllImport 问题/访问冲突

问题描述 投票:0回答:1

我正在尝试将具有 C 调用约定的 C++ 库移植到 c#

该项目位于 https://github.com/Esri/lepcc

我正在尝试移植示例 C++ 应用程序并使用 Lepcc C++ 项目中的 .DLL。

当应用程序结束时,我遇到访问冲突(内存损坏),但变量 ptVec 中的数据是正确的并且与 C++ 示例应用程序匹配,因此我部分存在。

我已经在示例代码中找到了此 C++ 函数的问题,该函数在调用时会导致访问冲突。

vector<Point3D> ptVec(nPts);
errCode = (ErrCode)lepcc_decodeXYZ(ctx, &ptr, (int)(len - pos), &nPts, (double*)(&ptVec[0]));

C++ 方法声明如下所示

lepcc_status lepcc_decodeXYZ(lepcc_ContextHdl _ctx, const unsigned char** ppByte, int bufferSize,
 unsigned int* nPtsInOut, double* xyzBuffOut)

在 c# 中,我已将调用翻译为以下内容(可能正确,也可能不正确)

[DllImport(LepccDll, CallingConvention = CallingConvention.Cdecl)]
public static extern lepcc_status lepcc_decodeXYZ(IntPtr ctx, ref IntPtr ppByte, int bufferSize,
 ref uint nPtsInOut, double[] xyzBuffOut);

和我的 C# 调用实现

var slpkBytes = System.IO.File.ReadAllBytes(fnIn);
long slpkLength = new FileInfo(fnIn).Length;
IntPtr ctx = LepccInterop.lepcc_createContext();
GCHandle slpkBytesPinned = GCHandle.Alloc(slpkBytes, GCHandleType.Pinned);
IntPtr ptr = slpkBytesPinned.AddrOfPinnedObject() + pos;

double[] ptVec = new double[(int)nPts * 3];
errCode = (ErrorCode)LepccInterop.lepcc_decodeXYZ(ctx, ref ptr, (int)(slpkLength - pos), ref nPts, ptVec);

slpkBytesPinned.Free();
LepccInterop.lepcc_deleteContext(ctx);           

我的 DllImport 看起来正确吗?我已经超出了我的深度。

c# c++ dllimport
1个回答
0
投票

我通过大量的试验和错误发现了以下内容。

在 C++ api 中,deleteContext 方法是这样声明的

void lepcc_deleteContext(lepcc_ContextHdl* ctx)
{
    delete reinterpret_cast<CtxImpl*>(*ctx);
    *ctx = nullptr;
}

并像这样使用

lepcc_ContextHdl ctx = lepcc_createContext();
lepcc_deleteContext(&ctx);

但是在c#中

[DllImport(LepccDll, CallingConvention = callingConvension)]
public static extern void lepcc_deleteContext(IntPtr ctx);

并这样称呼

  LepccInterop.lepcc_deleteContext(ctx);

这些不一样 - 在 C++ 中我们传递 ctx 的地址,但在 C# 中我传递 IntPtr

所以在 c# 中我应该调用这样的 C++ 方法(注意没有 *)

void lepcc_deleteContext(lepcc_ContextHdl ctx)
{
    delete reinterpret_cast<CtxImpl*>(ctx);
    //*ctx = nullptr;
}

然后它就可以工作了,没有例外。我不知道如何处理 C# 中的 * 到 ctx

我无法使用以下

lepcc_deleteContext(&ctx);
© www.soinside.com 2019 - 2024. All rights reserved.