将Stasm与C#-DllImport/Interop一起使用

将Stasm与C#-DllImport/Interop一起使用,c#,interop,pinvoke,C#,Interop,Pinvoke,我知道以前有人问过这个问题,不幸的是,提供的答案无法解决我的问题。我正在C#应用程序中使用statsm()库。下面是我调用“AsmSearchDll”函数的代码 [DllImport(@"stasm\stasm_dll.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern void AsmSearchDll ( [Out] out Int32 pnlan

我知道以前有人问过这个问题,不幸的是,提供的答案无法解决我的问题。我正在C#应用程序中使用statsm()库。下面是我调用“AsmSearchDll”函数的代码

        [DllImport(@"stasm\stasm_dll.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern void AsmSearchDll
    (
        [Out] out Int32 pnlandmarks,
        [Out] out Int32[] landmarks,
        [In, MarshalAs(UnmanagedType.LPStr)] String image_name,
        [In, MarshalAs(UnmanagedType.LPStr)] String image_data,
        [In] Int32 width,
        [In] Int32 height,
        [In] Int32 is_color,
        [In, MarshalAs(UnmanagedType.LPStr)] String conf_file0,
        [In, MarshalAs(UnmanagedType.LPStr)] String conf_file1
    );

    public void SearchFacialFeatures()
    {
        string image_name = "image-5.jpg"; // imagePath;
        var image = new Image<Bgr, byte>(image_name).Convert<Gray, byte>();

        int pnlandmarks = 0;
        var landmarks = new int[500];

        var imageData = Marshal.PtrToStringAnsi(image.MIplImage.imageData);
        int imgWidth = image.Width;
        int imgHeight = image.Height;
        int is_color = 1;
        string confile_file0 = Path.GetFullPath(@"data\mu-68-1d.conf");
        string config_file1 = Path.GetFullPath(@"data\mu-76-2d.conf");
        string sDataDir = @"\stasm\data";


        AsmSearchDll(out pnlandmarks, out landmarks, image_name, imageData, imgWidth, imgHeight, 1, null, null);

        MessageBox.Show(image_name);
    }
开始时,只要调用AsmSearchDll函数,应用程序就会退出,在对代码进行大量处理后,该函数停止。现在应用程序启动了,但是AsmSearchDll函数从未被处理过。我可以告诉你,因为我用VS浏览了代码。函数下面的消息框从未到达

我强烈感觉函数抛出了内部错误。对我来说不幸的是,这是我第一次处理Interop/DllImport

我的问题是,我做错了什么,如何解决这个问题?我已经做了一天多了

编辑:为非托管函数添加了代码

void AsmSearchDll (
int *pnlandmarks,          // out: number of landmarks, 0 if can't get landmarks
int landmarks[],           // out: the landmarks, caller must allocate
const char image_name[],   // in: used in internal error messages, if necessary
const char image_data[],   // in: image data, 3 bytes per pixel if is_color
const int width,           // in: the width of the image
const int height,          // in: the height of the image
const int is_color,        // in: 1 if RGB image, 0 if grayscale
const char conf_file0[],   // in: 1st config filename, NULL for default
const char conf_file1[])   // in: 2nd config filename, NULL for default, "" if none
非托管函数的签名

void AsmSearchDll (
int *pnlandmarks,          // out: number of landmarks, 0 if can't get landmarks
int landmarks[],           // out: the landmarks, caller must allocate
const char image_name[],   // in: used in internal error messages, if necessary
const char image_data[],   // in: image data, 3 bytes per pixel if is_color
const int width,           // in: the width of the image
const int height,          // in: the height of the image
const int is_color,        // in: 1 if RGB image, 0 if grayscale
const char conf_file0[],   // in: 1st config filename, NULL for default
const char conf_file1[])   // in: 2nd config filename, NULL for default, "" if none
调用函数的C++示例

    const char *image_name = "../data/test-image.jpg";

IplImage *img = cvLoadImage(image_name, CV_LOAD_IMAGE_COLOR);
if(img == NULL) {
    printf("Error: Cannot open %s\n", image_name);
    return -1;
}
// sanity checks (AsmSearchDll assumes imageData is vector of b,r,g bytes)

if(img->nChannels != 3 || img->depth != IPL_DEPTH_8U ||
        img->origin != 0 || img->widthStep != 3 * img->width) {
    printf("Error: %s is an unrecognized image type\n", image_name);
    return -1;
}

// locate the facial landmarks with stasm

int nlandmarks;
int landmarks[500]; // space for x,y coords of up to 250 landmarks
AsmSearchDll(&nlandmarks, landmarks,
             image_name, img->imageData, img->width, img->height,
             1 /* is_color */, NULL /* conf_file0 */, NULL /* conf_file1 */);
感谢您的帮助。

使用以下定义:

[DllImport(@"stasm\stasm_dll.dll", CallingConvention = CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
internal static extern void AsmSearchDll
(
    [Out] out Int32 pnlandmarks,
    [Out] Int32[] landmarks,       // <-- the `out` keyword is removed
    [In, MarshalAs(UnmanagedType.LPStr)] String image_name,
    [In] IntPtr image_data,        // <-- should not be passed as string
    [In] Int32 width,
    [In] Int32 height,
    [In] Int32 is_color,
    [In, MarshalAs(UnmanagedType.LPStr)] String conf_file0,
    [In, MarshalAs(UnmanagedType.LPStr)] String conf_file1
);
[DllImport(@“stasm\stasm_dll.dll”,CallingConvention=CallingConvention.Cdecl,CharSet=CharSet.Ansi)]
内部静态外部无效AsmSearchDll
(
[Out]Out Int32 pn地标,

[Out]Int32[]landmarks,//您的问题是,您的程序试图在../data/%filename%中查找某些文件,这会导致查找包含调试和发布文件夹的bin文件夹,而您的工作目录实际上是调试或发布,具体取决于您的配置。这就是程序返回代码0x01和0x01的原因错误。一个简单的解决方案是将包含所有必需文件的数据文件夹复制到调试或发布文件夹的父文件夹,这应该是一个快速解决方案,或者您可以通过修改dll为这些文件夹查找的文件夹路径来解决此问题


这个问题是因为路径是硬编码的。< /P>请提供非托管函数的签名。例如,C++中如何调用它?@ M.UnrOn。我已经包含了非托管函数签名的代码。我已经修改了我的定义,但是现在回到了以前的行为。应用程序在到达TH时退出。“AsmSearchDll”函数。你没有得到任何异常吗?没有,它没有引发任何异常。我甚至试着从bin目录运行.exe应用程序,看看它是否会引发异常,但什么都没有发生。这可能是由未指定的依赖dll引起的吗?如果你有原始dll的代码(我想你有),您可以用另一种方式从非托管代码中调试它。这样您就可以检查非托管端发生了什么。@Syma如果您可以在某个地方上载一个工作示例项目,我可以查看一下。