It's just as the title says.
I would like to reuse the dll that I created in the past and call it using a structure containing variables of double pointers (the real thing is a char array), but the following exceptions have occurred and it doesn't work.
[Exception]
System.TypeInitializationException: 'PayGwApp.ComTask' type initializer threw an exception.
AccessViolationException—An attempt was made to read or write to protected memory.Other memory may be corrupted.
The structures are as follows:
unsafe structure cmdq{
public ulong Size;
public char**ppData;
}
I want to set the array data in ppData and call the c++ side function, but it doesn't work.
The implementation is as follows:
// Function you want to call
[DllImport("mycmdq.dll")]
private external static long cmdq_exec(ushorti_id, IntPtr CmdQ);
private unsafe void InitData()
{
cmdqt_cmdQ = new cmdq();
t_cmdQ.Size=200;
try
{
char [ ] Data = new char [200];
// DUMMY FOR TEST
for (int idx=0; idx<Data.Length;idx++)
{
Data [idx] = (char) (idx+1);
}
fixed(char*pData=&Data[0])
{
t_cmdQ.ppData=&pData;
}
IntPtrcmdqPtr=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ulong))+Marshal.SizeOf(typeof(char))*Data.Length);
Marshall.StructureToPtr(t_cmdQ,cmdqPtr,false);
ret = cmdq_exec(20, cmdqPtr);
Console.WriteLine("sndbuf" + ret.ToString());
Marshall.FreeCoTaskMem (cmdqPtr);
}
catch (Exception exception)
{
Console.WriteLine("");
}
}
I've tried many things, but I can't solve them.
If you are familiar with it, could you please help me?
There are many problems with the source code listed, so I can point it out, but I can't give you the code to solve it because I don't know what the correct action is being asked for.
fixed
suppresses memory movement for a period of time in a statement.Memory movement can occur because it is released when a statement is left out.Therefore, it is wrong to keep the pointer obtained in the fixed
statement.
Marshal.AllocHGlobal
corresponds to Marshal.FreeCoTaskMem
corresponds to Marshal.AllocCoTaskMem
.The response is not correct.
C# ulong
is a 64-bit unsigned integer, and C++ corresponds to uint64_t
.unsigned long
in Windows C++ is defined as 32 bits, so it is not correct if you are expecting this.
Similarly, C# char
represents a 16-bit Unicode character.C++ corresponds to char16_t
.char
in Windows C++ represents an 8-bit ANSI character, so if you're expecting this, it's not correct.
In order to get a pinpoint answer to the phenomenon of the question, it would have been faster if you had the structure cmdq
definition or the cmdq_exec
entry part source.
If you say dll that you made in the past, you should have the source yourself.
For example, if you create a dummy C++ dll in VS2019, the moving version will have this source.It only checks the validity of the call, recovery, and parameter data.
In Unicode mode, both C# and C++ were built in 32 bits.
#include "pch.h"
BOOL APIENTRY DllMain (HMODULE hModule, DWORDul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
typeef structure cmdq {
ULONGLONG Size;//## If this is ULONG, make C# side uint
TCHAR**ppData;
};
//## Is the following cmdqptr type pointer cmdq*?
external "C" __declspec(dllexport) long cmdq_exec(USHORT i_id, cmdq*cmdqptr)
{
TCHAR**ppData=cmdqptr->ppData;
TCHAR*pData=*ppData;
for (ULONGLONG i=0;i<cmdqptr->Size;i++)
{
TCHAR c=pData[i]; //### This process is meaningless, but if it is in Debug mode, it will be checked.
}
return(long)cmdqptr->Size;
}
Check if the above part of C++ dll and the build's Unicode/ANSI mode are correct.I think it's a good idea to make these dummies and check them one by one.
Based on the phrase "System.TypeInitializationException: 'PayGwApp.ComTask' type initializer threw an exception", the above has actually been cleared and the problem may have occurred within the true cmdq_exec
.
The only way to investigate this is to incorporate a complete set of dll projects that you created in the past into the C# solution and run them both in debug mode.
© 2024 OneMinuteCode. All rights reserved.