i p verwenden/ruft eine Reihe von "DN_OPstruct" s von meinem nicht verwalteten Code zurück:P/Invoke Zurückgeben Array von Strukturen mit String-Feldern
struct DN_OPstruct {
const char* TargetNode_Identifier;
const char* Name;
int TargetNode_NamespaceIndex;
...
};
EXTERN_C UA_EXPORT_WRAPPER_IMPORT int getOpToArr(const char* _rootGuid, DN_OPstruct ** array, int * arraySizeInElements){
std::list<UA_Ref_and_TargetNode> uaList;
uaList = getLisT(...)
*arraySizeInElements = uaList.size();
int bytesToAlloc = sizeof(DN_OPstruct) * (*arraySizeInElements);
DN_OPstruct * a = static_cast<DN_OPstruct*>(CoTaskMemAlloc(bytesToAlloc));
*array = a;
for (UA_Ref_and_TargetNode &i: uaList){
DN_OPstruct iterOp;
iterOp = getOp(...);
opList.push_back(iterOp);
}
return 1;
}
Mein Managed-Code wie folgt aussieht:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DN_OPstruct
{
private IntPtr TargetNode_Identifier;
private IntPtr NamePtr;
public string Guid
{
get { return Marshal.PtrToStringAnsi(TargetNode_Identifier); }
set { TargetNode_Identifier = Marshal.StringToHGlobalAnsi(value); }
}
public string Name
{
get { return Marshal.PtrToStringAnsi(NamePtr); }
set { NamePtr = Marshal.StringToHGlobalAnsi(value); }
}
public int TargetNode_NamespaceIndex;
...
};
[DllImport(@"...", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "getOpToArr",
ExactSpelling = true, CharSet = CharSet.Ansi)]
public static extern int getOpToArr([MarshalAs(UnmanagedType.LPStr)]string myNodeGuid,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] out DN_OPstruct[] array, out int arraySizeInElements);
Wenn ich versuche, die Methode aufzurufen, werde ich in den nicht verwalteten Code springen und kann es erfolgreich debuggen und ich bekomme ein Array mit meinem DN_OPstructs zurück. Allerdings, wenn ich seine Felder ausgelesen wie .Name oder .Guid, bekomme ich diesen Fehler:
First-chance exception at 0x000007fefd921757 in (...).exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
If there is a handler for this exception, the program may be safely continued.
Ich habe versucht, „ArraySubType = UnmanagedType.LPStruct“ zu meiner Methode Erklärung hinzuzufügen; Es hat nicht geholfen.
Ich habe gerade Stunden damit verbracht, P/Invoke in einem ähnlichen Szenario arbeiten zu lassen. Ich habe am Ende eine C++/CLR-Wrapper-Bibliothek geschrieben. Ich fand es viel einfacher, mit verwaltetem/nicht verwaltetem Code aus C++ umzugehen. Ich habe einfach alles in ein paar CLR-Klassen abgebildet, und wenn Sie ref zu diesem Projekt hinzufügen, können Sie diese Klassen verwenden, als wären sie C# (weil sie .NET-kompatibel geschrieben sind). – AlexanderBrevig