Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(C)从C+获取字符**时的AccessViolationException+;动态链接库 我编写了一个基本的C++库,它从OPC UA服务器获取数据并将其格式化为字符串数组(char *)。我已经确认它是独立工作的,但现在我正试图使用DLL/pInvoke从C#程序调用它,并遇到严重的内存错误 StringData theStringData = /*get the data*/; Marshal.StructureToPtr(theStringData, pnt, false); // Place structure into unmanaged space. getTopLevelNodes(/* data */, pnt); // call dll theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData)); //get structure back from unmanaged space. Marshal.FreeHGlobal(pnt); // Free shared mem_C#_C++_Dll_Interop_Access Violation - Fatal编程技术网

(C)从C+获取字符**时的AccessViolationException+;动态链接库 我编写了一个基本的C++库,它从OPC UA服务器获取数据并将其格式化为字符串数组(char *)。我已经确认它是独立工作的,但现在我正试图使用DLL/pInvoke从C#程序调用它,并遇到严重的内存错误 StringData theStringData = /*get the data*/; Marshal.StructureToPtr(theStringData, pnt, false); // Place structure into unmanaged space. getTopLevelNodes(/* data */, pnt); // call dll theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData)); //get structure back from unmanaged space. Marshal.FreeHGlobal(pnt); // Free shared mem

(C)从C+获取字符**时的AccessViolationException+;动态链接库 我编写了一个基本的C++库,它从OPC UA服务器获取数据并将其格式化为字符串数组(char *)。我已经确认它是独立工作的,但现在我正试图使用DLL/pInvoke从C#程序调用它,并遇到严重的内存错误 StringData theStringData = /*get the data*/; Marshal.StructureToPtr(theStringData, pnt, false); // Place structure into unmanaged space. getTopLevelNodes(/* data */, pnt); // call dll theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData)); //get structure back from unmanaged space. Marshal.FreeHGlobal(pnt); // Free shared mem,c#,c++,dll,interop,access-violation,C#,C++,Dll,Interop,Access Violation,我的C#main: StringData theStringData = /*get the data*/; Marshal.StructureToPtr(theStringData, pnt, false); // Place structure into unmanaged space. getTopLevelNodes(/* data */, pnt); // call dll theStringData =(St

我的C#main:

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
List resultList=new List();
IntPtr inArr=新的IntPtr();
inArr=Marshal.AllocHGlobal(inArr);
resultList=Utilities.ReturnStringArray(/*data*/,inArr);
C#辅助函数:

public class Utilities{

    [DllImport(//DllArgs- confirmed to be correct)]
    private static extern void getTopLevelNodes(/*data*/, IntPtr inArr);

    public static List<String> ReturnStringArray(/*data*/,IntPtr inArr)
    {

       getTopLevelNodes(/*data*/,inArr); // <- this is where the AccessViolationException is thrown
       //functions that convert char ** to List<String>
       //return list
    }
StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
公共类实用程序{
[DllImport(//DllArgs-确认正确)]
私有静态外部void getToLevel节点(/*data*/,IntPtr inArr);
公共静态列表ReturnStringArray(/*data*/,IntPtr inArr)
{

getToLevel节点(/*data*/,inArr);/方法1-高级结构编组。

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
与编组列表不同,请尝试创建如下c#结构:

[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct StringData
{
    public string [] mylist; /* maybe better yet byte[][] (never tried)*/
};
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(StringData)); // Into Unmanaged space
StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
现在在c#marshall中,像这样:

[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct StringData
{
    public string [] mylist; /* maybe better yet byte[][] (never tried)*/
};
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(StringData)); // Into Unmanaged space
StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
获取指向该结构的指针

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
现在在CPP:

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
#pragma pack(2)
/************CPP STRUCT**************/
struct StringDataCpp
{
    char * strings[]
}; 
以及功能:

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
extern "C" EXPORT void getTopLevelNodes(/*data*/,char *ret){ //just a byte pointer.   

struct StringDataCpp *m = reinterpret_cast<struct StringDataCpp*>(ret);

//..do ur thing ..//

}
现在

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
CPP只接收字符*。现在需要一个分隔符来分隔字符串。 请注意,您的字符串可能已经使用DELIMETER“\0”使用替换算法将其替换为“;”或其他内容,并使用STRTOK和“;”作为分隔符或使用BOOST在CPP中的循环中轻松标记

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
或者,如果可能,尝试创建字节指针数组

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
Byte*[i] theStringStartPointers = &stringList[i]/* in a for loop*/
fixed(byte* *cp = theStringStartPointers) /// Continue

这种方法更简单。
不安全
块允许
固定
块,而固定块确保c#内存管理机制不会移动该数据。

方法1-高级结构编组。

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
与编组列表不同,请尝试创建如下c#结构:

[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct StringData
{
    public string [] mylist; /* maybe better yet byte[][] (never tried)*/
};
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(StringData)); // Into Unmanaged space
StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
现在在c#marshall中,像这样:

[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct StringData
{
    public string [] mylist; /* maybe better yet byte[][] (never tried)*/
};
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(StringData)); // Into Unmanaged space
StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
获取指向该结构的指针

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
现在在CPP:

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
#pragma pack(2)
/************CPP STRUCT**************/
struct StringDataCpp
{
    char * strings[]
}; 
以及功能:

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
extern "C" EXPORT void getTopLevelNodes(/*data*/,char *ret){ //just a byte pointer.   

struct StringDataCpp *m = reinterpret_cast<struct StringDataCpp*>(ret);

//..do ur thing ..//

}
现在

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
CPP只接收字符*。现在需要一个分隔符来分隔字符串。 请注意,您的字符串可能已经使用DELIMETER“\0”使用替换算法将其替换为“;”或其他内容,并使用STRTOK和“;”作为分隔符或使用BOOST在CPP中的循环中轻松标记

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
或者,如果可能,尝试创建字节指针数组

StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem
Byte*[i] theStringStartPointers = &stringList[i]/* in a for loop*/
fixed(byte* *cp = theStringStartPointers) /// Continue

这种方法要简单得多。
unsafe
块允许
fixed
块,而fixed则确保c#内存管理机制不会移动该数据。

由于我不确定且无法测试它,所以不将其作为答案,但您是否尝试过使用
IntPtr[]
而不是
IntPtr
,因为从某种意义上讲,您传递的是一个指针数组,而不仅仅是一个指针。另外,作为旁注,我相信您的第一个数组元素有一个1个字符的内存泄漏,因为您为它malloc了一个位置,然后在循环的第一次迭代中再次调用malloc。@pstrjds谢谢,我会修复它的。@pstrjds不知道你的情况,但是你是否可以在C++调用周围创建一个C++/CLI包装器?然后你可以有一个类来填充填充向量,然后把数据推到.NET结构上,以便在你的C端上进行消费。不要把它当作我不确定的答案,不能测试它,但是你试过使用<代码>tPtr[]
而不是
IntPtr
,因为从某种意义上讲,您传递的是一个指针数组,而不仅仅是一个指针。另外,作为旁注,我相信您的第一个数组元素有一个1个字符的内存泄漏,因为您为它malloc了一个位置,然后在循环的第一次迭代中再次调用malloc。@pstrjds谢谢,我会修复它的。@pstrjds不知道你的情况,但是你是否可以在你的C++调用周围创建一个C++/CLI包装器?然后你可以有一个类来填充这个向量,然后把数据推到.NET结构上,以便在你的C端上消费。这个看起来很有前途,我会尝试实现并返回给你。谢谢!ngs请确保您注意到我的编辑,您必须封送.sizeof(theStringData),因为字符串大小是在运行时确定的。理想情况下,结构的大小是确定的。即一定数量的字节数组具有一定大小。byte[5][12]。@T.Meads事实上,因为您只使用字符串,我喜欢我的“方法2”这对你来说更好。问题是我的程序一次处理多达数千个字符串的大量数据。我不认为把所有数据都放在一个大的分隔字符*字符串中是好的,内存管理是明智的嗯,好吧,我将把所有这些都作为你可能使用的工具,所以这里还有一个想法。只是认识到e一个IntPtr指向HGlobal(非托管堆全局)从这里开始,cpp必须解释在何处将该内存拆分为单独的字符串。您可能需要传入一个IntPtr数组,每个IntPtr都是对其中一个字符串的引用。或者修复一个byte*cp=anArrayOfBytePointers;然后在cpp中重新解释为一个单独的char*数组,该数组也可用于构造std::stringsThis看起来很有希望,我会尝试实现并回复您。谢谢!@T.Meads因为这些是字符串确保您注意到我的编辑,您必须封送.sizeof(theStringData),因为字符串大小将在运行时确定。理想情况下,结构的大小是确定的。即一定数量的字节数组具有一定大小。字节[5][12].@T.Meads事实上,因为您只使用字符串,所以我喜欢我的“方法2”这对你来说更好。问题是我的程序一次处理多达数千个字符串的大量数据。我不认为把所有数据都放在一个大的分隔字符*字符串中是好的,内存管理是明智的嗯,好吧,我将把所有这些都作为你可能使用的工具,所以这里还有一个想法。只是认识到如果一个IntPtr指向一个HGlobal(非托管堆全局),那么cpp将不得不解释spl的位置
StringData theStringData = /*get the data*/;
Marshal.StructureToPtr(theStringData, pnt, false);
                                    // Place structure into unmanaged space.

getTopLevelNodes(/* data */, pnt); // call dll

theStringData =(StringData)Marshal.PtrToStructure(pnt,typeof(StringData));
                                    //get structure back from unmanaged space.
Marshal.FreeHGlobal(pnt); // Free shared mem