2

我的项目有问题: 在 dll c++ 中:

    extern "C" __declspec(dllexport) int results(char* imgInput, void* tree)
{   
    struct kd_node* nodeTree = new(tree)kd_node ; // new kd_tree with data from memory address
    ...

    ...
    int ret = atoi(retValueStr.c_str());
    return ret;
}

extern "C" __declspec(dllexport) void* buildKDTree(char* folder)
{
    struct kd_node* kd_root;
    ....

    feature *LFData = listFeat.data();
    kd_root = kdtree_build(LFData,listFeat.size());
    void* address_kdtree = (void*)&kd_root; // get memory address of kd_tree
    return address_kdtree;
}

我在 c# 中使用 dllimport:

[DllImport(@"kdtreeWithsift.dll", EntryPoint = "buildKDTree", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern void* buildKDTree(byte[] urlImage);


[DllImport(@"kdtreeWithsift.dll", EntryPoint = "results", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.I4)]
public unsafe static extern int results(byte[] imgInput, void* tree);

static unsafe void Main()
{
     string urlImg1 = "C:/Users../test img/1202001T1.jpg";
     string urlImg = "C:/export_features"; 

     try
     {  
     IntPtr result;
     int result1;
     result1 = results(convertStringToByte(urlImg1), 5, buildKDTree(convertStringToByte(urlImg))); //  this error
     Console.WriteLine("results = %d",result1);
     }
     catch (Exception ex)
     {
          Console.WriteLine(ex);
          Console.ReadLine();
     }
}

当我运行该程序时,该程序显示错误:尝试读取或写入受保护的内存。这通常表明其他内存已损坏

你知道什么错误以及如何解决?谢谢你!

4

4 回答 4

1

你在这里不需要convertStringToByte方法。您可以告诉运行时将您的字符串编组为char *. 另外,我建议您使该方法返回 an IntPtr,如下所示:

[DllImport(@"kdtreeWithsift.dll", EntryPoint = "buildKDTree",
    CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr buildKDTree([MarshalAs(UnmanagedType.LPStr)]string urlImage);

[DllImport(@"kdtreeWithsift.dll", EntryPoint = "results",
    CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[return:MarshalAs(UnmanagedType.I4)]
public static extern int results([MarshalAs(UnmanagedType.LPStr)]string imgInput, IntPtr tree);

然后,您可以使用以下命令调用它:

IntPtr tree = buildKDTree(urlImg);
int result1 = results(urlImg, 50, tree);

Console.WriteLine("results = {0}",result1);
于 2013-05-21T16:50:59.333 回答
0

好吧,一方面,C 函数称为 buildKDTree,但您是在 C# 代码中使用入口点“buildKDTreeWithFeatures”导入它。试着让这些一致,看看你是否能得到更好的结果。

于 2013-05-21T16:21:30.780 回答
0

我认为由于char * 参数引起的类似问题,在我自己的问题中,感谢以下链接问题解决了问题。

因此,您唯一的解决方案是将字符串参数作为 IntPtr 传递。使用 Marshal.StringToHGlobalAnsi 分配内存

尝试在 c# 中使用 dllimport 读取或写入受保护的内存

于 2015-03-02T11:01:45.983 回答
0

我试着叫它:

IntPtr tree = buildKDTree(urlImg);
int result1 = results(urlImg, 50, tree);

Console.WriteLine("results = {0}",result1);

但你说的地方不是你的错。我认为导致错误intPtr tree的函数中的变量results([MarshalAs(UnmanagedType.LPStr)]string imgInput, IntPtr tree);

于 2013-05-22T01:57:22.987 回答