2
votes

I am trying to make a C++/CLI wrapper for Caffe to c#. I have made my own classification project on top on libcaffe. The classification project works perfectly when called from a c++ console project.

I have made an empty wrapper project that compile and can be called from c#

CaffeWrapper.h

#pragma once
//#include "classification.h"
namespace CaffeWrapper {

public ref class Detector
{   
public:
    Detector(System::String^ model_file,
        System::String^ trained_file,
        System::String^ label_file);

private:
    //Classifier * c;

CaffeWrapper.cpp

#include "CaffeWrapper.h"
#include <msclr\marshal_cppstd.h>
namespace CaffeWrapper {
Detector::Detector(System::String^ model_file,
    System::String^ trained_file,
    System::String^ label_file)
{
    std::string unmanaged_model = 
      msclr::interop::marshal_as<std::string>(model_file);
    std::string unmanaged_train = 
      msclr::interop::marshal_as<std::string>   (trained_file);
    std::string unmanaged_label = 
      msclr::interop::marshal_as<std::string>(label_file);

    //c = new Classifier(unmanaged_model, unmanaged_train, unmanaged_label);
}

Test program in c#

using System;
using System.IO;
using CaffeWrapper;
namespace TestDetect 
{
    class Program
    {
        static void Main(string[] args)
        {
            string basePath = "C:/Caffe/TestClassify/";
            string model_file = basePath + "net.prototxt";
            string trained_file = basePath + "lenet_iter_20000.caffemodel";
            string label_file = basePath + "labels.txt";
            string imgfile = basePath + "imageTest.pgm";
            Console.WriteLine("test");
            var detecotr = new Detector(model_file, trained_file, label_file);
        }
    }
}

When i include my classification project in my wrapper

#include "classification.h"

I get the following error on startup:

A first chance exception of type 'System.AccessViolationException' occurred in mscorlib.dll Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Isn't this an error reading or writing unallocated memory? How can get this at startup? Do you have any solutions for this problem?

Call stack:

mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)

mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()

EDIT: There seems to be some problem with the references to .NET in my wrapper. The reference to system had a red exclamation. I removed it and now when I try to add it I get error: Error HRESULT E_FAIL has been returned from a call to a COM component.

1
you want call native C++ in C# code? or vice verse?Matt
This happens very early, even before your C# code starts running. Note how Main() is not in the stack trace. The trigger is the jitter loading your C++/CLI assembly which in turn gets the native code to initialize itself. Static initialization bugs in C++ are very hard to diagnose, the infamous "static initialization order fiasco" problem in C++ can ruin a week of your life. An important first step is to enable unmanaged debugging so you at least have something to look at.Hans Passant
@Matt I want to call c++Björn
@Björn, then you don't need a C++/CLI wrapper, you can just use pinvokeMatt

1 Answers

0
votes

AccessViolationException usually suggests an attempt to use a null c++ pointer The call stack further suggests the problem is with a static initialiser as opposed to execution of your main routine - I don't know about caffe but I would look at statics in classification.h (or one of its dependencies) and check that valid initialisation is being carried out