如果我在C++中直接运行我的代码,它就运行得很好。但是,当我从C#调用它时,我会得到一个错误的分配消息。我的C++经验确实很低,但我觉得基于我所阅读和修改的所有内容,这应该是可行的。
我的处境
将图像路径通过面部识别,然后将结果保存/序列化到磁盘,并返回数组中的图像索引(函数: int AddImageToCollection)
如果我使用主函数运行我的代码,就会得到完美的结果(图1),但是如果我通过C# (图2)运行它,我会得到以下结果:
我得到的是log 4-1,而不是log 4-2,e.what()中唯一的错误是“错误分配”。我创建了一个没有参数的测试函数,该函数难以编码返回5,因此它与这个更复杂的函数隔离,我认为它必须与将数据传递给const char*有关。
图1
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor sp;
anet_type net;
bool fileExists(const std::string& name) {
ifstream f(name.c_str());
return f.good();
}
void log(std::string name) {
}
int main(int argc, char** argv) try
{
string str = "C:\\images\\Me.jpg";
const char* c = str.c_str();
int whatIsMyIdx = AddImageToCollection(c);
cout << whatIsMyIdx << endl;
cin.get();
}
catch (std::exception& e)
{
cout << e.what() << endl;
}
int AddImageToCollection(const char* imagePath)
{
deserialize("shape_predictor_5_face_landmarks.dat") >> sp;
deserialize("dlib_face_recognition_resnet_model_v1.dat") >> net;
matrix<rgb_pixel> image;
string imagePathStr(imagePath);
load_image(image, imagePathStr);
std::vector<matrix<rgb_pixel>> faces;
if (fileExists("faces_in_collection.dat")) {
deserialize("faces_in_collection.dat") >> faces;
}
auto facesDetected = detector(image);
if (facesDetected.size() == 0) { return -1; }
if (facesDetected.size() > 1) { return -2; }
auto shape = sp(image, facesDetected[0]);
log("4-1");
matrix<rgb_pixel> face_chip;
extract_image_chip(image, get_face_chip_details(shape, 150, 0.25), face_chip);
log("4-2");
faces.push_back(move(face_chip));
serialize("faces_in_collection.dat") << faces;
std::vector<matrix<float, 0, 1>> face_descriptors;
if (fileExists("face_descriptors_in_collection.dat")) {
deserialize("face_descriptors_in_collection.dat") >> face_descriptors;
}
face_descriptors.push_back(net(faces[faces.size() - 1]));
serialize("face_descriptors_in_collection.dat") << face_descriptors;
return faces.size() - 1; //Return Image's Index in Array
}图2
[DllImport("FacialRecognition.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int TestImageToCollection();
[DllImport("FacialRecognition.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int AddImageToCollection([MarshalAs(UnmanagedType.LPStr)]string imagePath);
private void Form1_Load(object sender, EventArgs e)
{
int whatIsMyTestIdx = TestImageToCollection();
int whatIsMyIdx = AddImageToCollection(@"C:\images\Me.jpg");
MessageBox.Show(whatIsMyIdx.ToString());
}发布于 2018-08-15 12:04:26
您需要调整代码如下
在DLL中
extern "C" __declspec(dllexport) int AddImageToCollection(LPCWSTR imagePath) { .... // you may need to convert from Unicode string to ANSI if you are calling function that accept ANSI strings }
在c#应用程序中
[DllImport("FacialRecognition.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern int AddImageToCollection(string imagePath);然后调用你的函数就像
int whatIsMyIdx = AddImageToCollection(@"C:\\images\\Me.jpg");要使上述程序正确工作,请不要忘记将应用程序和Dll编译为Unicode。如果它们不同,则应调整正确的导出和导入声明。
https://stackoverflow.com/questions/51857061
复制相似问题