尝试调用导入的C ++函数时C#:AccessViolationException

时间:2013-12-09 15:59:46

标签: c# c++ dllimport access-violation

我一直在阅读很多有关此问题的帖子,但我无法修复它。

我正在尝试导入此函数(最初用C ++编写)

__declspec( dllexport ) int __stdcall GeekFunction(void *indices, 
    unsigned int *vertexRemap,
    unsigned int numIndices, 
    unsigned int numVertices, 
    int indexFormat,
    void *allocator);

到我的C#项目:

[DllImport("sce_psp2vertexcache.dll", 
           CallingConvention = CallingConvention.StdCall, 
           EntryPoint = "GeekFunction")]

unsafe private static extern int GeekFunction(
    [In, Out] IntPtr indices, 
    [Out] IntPtr vertexRemap, 
    [In] UInt32 numIndices, 
    [In] UInt32 numVertices, 
    [In] int indexFormat, 
    [In] void* allocator);

我用这种方式调用函数:

UInt32[] vertexRemap = new UInt32[locs.data.Length * 6];
GCHandle handleVertexRemap = GCHandle.Alloc(vertexRemap, GCHandleType.Pinned);
GCHandle handleIndexdata = GCHandle.Alloc(indexdata, GCHandleType.Pinned);

if (GeekFunction(
         GCHandle.ToIntPtr(handleIndexdata),
         GCHandle.ToIntPtr(handleVertexRemap),
         Convert.ToUInt32(indexdata.Length),
         Convert.ToUInt32(locs.data.Length), 1, null) != 0)
                            StatusOutput.FatalError("Geekfunction Failed");

handleIndexdata.Free();

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

最后,我发现了发生了什么。

我使用相同的句柄多次给GeekFunction打电话:

if (GeekFunction(
         GCHandle.ToIntPtr(handleIndexdata),
         GCHandle.ToIntPtr(handleVertexRemap),
         Convert.ToUInt32(indexdata.Length),
         Convert.ToUInt32(locs.data.Length), 1, null) != 0)
                            StatusOutput.FatalError("Geekfunction Failed");

...

if (GeekFunction(
         GCHandle.ToIntPtr(handleIndexdata),
         GCHandle.ToIntPtr(handleVertexRemap),
         Convert.ToUInt32(indexdata.Length),
         Convert.ToUInt32(locs.data.Length), 1, null) != 0)
                            StatusOutput.FatalError("Geekfunction Failed");

如果我重建调用之间的句柄,我没有得到AccessViolationException:

try
                        {
                            if (GeekFunction(
                                handleBoneIndices.AddrOfPinnedObject(),
                                handleVertexRemap.AddrOfPinnedObject(),
                                Convert.ToUInt32(boneindices.data.Length),
                                Convert.ToUInt32(sizeof(VertexData.Index4)), null) != 0)
                                StatusOutput.FatalError("GeekFunctionFailed: boneIndices");
                        }
                        finally
                        {
                            handleBoneIndices.Free();
                            handleVertexRemap.Free();
                        }

**handleVertexRemap = GCHandle.Alloc(vertexRemap, GCHandleType.Pinned);**

try
                        {
                            if (scePsp2VertexCacheApplyVertexRemapping(
                                handleBoneIndices.AddrOfPinnedObject(),
                                handleVertexRemap.AddrOfPinnedObject(),
                                Convert.ToUInt32(boneindices.data.Length),
                                Convert.ToUInt32(sizeof(VertexData.Index4)), null) != 0)
                                StatusOutput.FatalError("scePsp2VertexCacheApplyVertexRemapping Failed: boneIndices");
                        }
                        finally
                        {
                            handleBoneIndices.Free();
                            handleVertexRemap.Free();
                        }

谢谢你的帮助。具有更简单功能的测试帮助很大。