You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been trying to get the c# wrapper to work for a while now. Sadly, every time I try to detect an image I keep getting System.AccessViolationExceptions. I've already tried catching them myself and trying to figure out what the issue was, but so far I've had no luck.
I've already tried to declare the functions CallingConventions, but that has not solved the issue so far. I'm still getting the errors whenever I call the dll function DetectImage.
I've also found that the formula for allocating memory in the Detect(byte[] image) class seems off. If I let it run as is the code will return a System.AccessViolationException when trying to call Marshal.Copy() on line 91. If I use the hardcoded value (the length of my testing image array) the code succesfully copies the array to the unmanaged memory, but it then crashes again when calling DetectImage on the line below.
Has anyone here succesfully ran the yolowrapper, and if so, could you please enlighten me what I am doing wrong?
Here's my code:
main:
class Program
{
static void Main(string[] args)
{
string configurationFilename = @"YoloFiles\yolov4-Test.cfg";
string weightsFilename = @"yolov4-Test_best.weights";
var handler = new MLHandler(configurationFilename, weightsFilename, 0);
byte[] image = File.ReadAllBytes(@"C:\Repos\Jvl\TempImages\Test.JPG");
var box = handler.Detect(image);
handler.Dispose();
foreach (var candidate in box)
{
Console.WriteLine("Object ID: " + candidate.obj_id);
Console.WriteLine("Probability: " + candidate.prob);
}
}
}
YoloWrapper:
public class YoloWrapper {
private const string YoloLibraryName = "darknet.dll";
private const int MaxObjects = 1000;
[DllImport(YoloLibraryName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]
[HandleProcessCorruptedStateExceptions]
private static extern int InitializeYolo(string configurationFilename, string weightsFilename, int gpu);
[DllImport(YoloLibraryName, EntryPoint = "detect_image", CallingConvention = CallingConvention.Cdecl)]
[HandleProcessCorruptedStateExceptions]
private static extern int DetectImage([MarshalAs(UnmanagedType.LPStr)] string filename, ref BboxContainer container);
[HandleProcessCorruptedStateExceptions]
[DllImport(YoloLibraryName, EntryPoint = "detect_mat", CallingConvention = CallingConvention.Cdecl)]
private static extern int DetectImage(IntPtr pArray, int nSize, ref BboxContainer container);
[HandleProcessCorruptedStateExceptions]
[DllImport(YoloLibraryName, EntryPoint = "dispose", CallingConvention = CallingConvention.Cdecl)]
private static extern int DisposeYolo();
[StructLayout(LayoutKind.Sequential)]
public struct bbox_t
{
public UInt32 x, y, w, h; // (x,y) - topleft corner, (w, h) - width & height of bounding box
public float prob; // confidence - probability that the object was found correctly.
public UInt32 obj_id;
public UInt32 track_id;
public UInt32 frames_counter;
public float x_3d, y_3d, z_3d; // 3-D coordonates, if there is a 3d stereo camera used
}
[StructLayout(LayoutKind.Sequential)]
public struct BboxContainer
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxObjects)]
public bbox_t[] candidates;
}
public YoloWrapper(string configurationFilename, string weightsFilename, int gpu)
{
InitializeYolo(configurationFilename, weightsFilename, gpu);
}
public void Dispose()
{
DisposeYolo();
}
[HandleProcessCorruptedStateExceptions]
public bbox_t[] Detect([MarshalAs(UnmanagedType.LPStr)] string filename)
{
var container = new BboxContainer();
try
{
var count = DetectImage(filename, ref container);
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
return null;
}
return container.candidates;
}
[HandleProcessCorruptedStateExceptions]
public bbox_t[] Detect(byte[] imageData)
{
var container = new BboxContainer();
var size = Marshal.SizeOf(imageData[0] * imageData.Length);
var hardcoded = 4967109;
var pnt = Marshal.AllocHGlobal(hardcoded - 1);
try
{
// Copy the array to unmanaged memory.
Marshal.Copy(imageData, 0, pnt, imageData.Length);
var count = DetectImage(pnt, imageData.Length, ref container);
if (count == -1)
{
throw new NotSupportedException($"{YoloLibraryName} has no OpenCV support");
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return null;
}
finally
{
// Free the unmanaged memory
Marshal.FreeHGlobal(pnt);
}
return container.candidates;
}
}
EDIT:
In a later test, where I removed the CallingConventions and used size*2 as input for Marshal.AllocHGlobal, the program exited with error code: -1073740940, which at the microsoft NTSTATUS converts to: 0xC0000374 or STATUS_HEAP_CORRUPTION.
Not sure if this could help any potentional nice helpers, but more information is never a bad thing.
EDIT 2:
After some more digging I've found the exact point in the assembly where the corrupted memory adress is referenced:
The memadress where the arrow is pointing (7FFDB329AA52) with the command mov dword ptr[rbp+4Ch], eax is where it stops working. This should mean the adress at ptr [rbp+4Ch] is somehow forbidden to access. Does anyone know how to change either the memory adress or the rights to access it?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I've been trying to get the c# wrapper to work for a while now. Sadly, every time I try to detect an image I keep getting System.AccessViolationExceptions. I've already tried catching them myself and trying to figure out what the issue was, but so far I've had no luck.
I've already tried to declare the functions CallingConventions, but that has not solved the issue so far. I'm still getting the errors whenever I call the dll function DetectImage.
I've also found that the formula for allocating memory in the Detect(byte[] image) class seems off. If I let it run as is the code will return a System.AccessViolationException when trying to call Marshal.Copy() on line 91. If I use the hardcoded value (the length of my testing image array) the code succesfully copies the array to the unmanaged memory, but it then crashes again when calling DetectImage on the line below.
Has anyone here succesfully ran the yolowrapper, and if so, could you please enlighten me what I am doing wrong?
Here's my code:
main:
YoloWrapper:
EDIT:
In a later test, where I removed the CallingConventions and used size*2 as input for Marshal.AllocHGlobal, the program exited with error code: -1073740940, which at the microsoft NTSTATUS converts to: 0xC0000374 or STATUS_HEAP_CORRUPTION.
Not sure if this could help any potentional nice helpers, but more information is never a bad thing.
EDIT 2:
After some more digging I've found the exact point in the assembly where the corrupted memory adress is referenced:
The memadress where the arrow is pointing (7FFDB329AA52) with the command mov dword ptr[rbp+4Ch], eax is where it stops working. This should mean the adress at ptr [rbp+4Ch] is somehow forbidden to access. Does anyone know how to change either the memory adress or the rights to access it?
Beta Was this translation helpful? Give feedback.
All reactions