0

I am using C DLL in C# code (.net 4.0) in a console application and facing issue. When I call the C method it raises the below exception.

"A call to PInvoke function 'ProcessFilesC' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

Here is the C code

    int ProcessFilesC(
        char **p_FilesOrDirs,
        ImageInfoC **p_vecImageInfo,
        int ***p_vecStackIndexes,
        RectC ***p_vecFaces
    );    

Here is my C# code

    [DllImport(@"..\ref\myCApp.dll", CallingConvention = CallingConvention.StdCall)]
    unsafe private static extern UInt16 ProcessFilesC(
               String[] p_FilesOrDirs,
               ref ImageInfoC[] p_vecImageInfo,
               out Int32[] p_vecStackIndexes,
               out RectC[] p_vecFaces
            );


    public unsafe struct ImageInfoC
    {            
        public String resizedFilePath;      //char*   (in C)
        public Byte isUsable;               //unsigned char (in C)
        public UInt32 imageId;              //long int in (in C)
        public UInt16 stackIndex;           //int (in C)
        public Boolean isBestPhoto;         //unsigned char  (in C)
    }

Below is C# code to call the method

    unsafe
        {
             iResult = ProcessFilesC(
                              p_FilesOrDirs,          // Value getting passed to DLL
                              ref p_vecImageInfo,
                              out p_vecStackIndexes,
                              out p_vecFaces
                        );
             Console.WriteLine("ProcessFilesC Complete");
        }

When code reaches here, I can see that method is processing as it prints in console but after processing, it raises the mentioned exception.

I guess this is due to C DLL is trying to write values in output/ref parameters. I am not getting where is the issue or what's the wrong in my code.

Please note that I have already uncheck option "Suppress JIT optimization on module load" at Tools -> Options -> Debugging -> General

Please help as soon as poosible.

Thanks for spending to valuable time to read this post.

Thanks, Kiran

Kiran
  • 1
  • 4

1 Answers1

1

The first thing to check is the calling convention. In most cases the calling convention specified in your DllImport attribute differs from the actual calling convention in the native DLL.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Thanks for replying Daniel but how can I check actual calling convention in the native DLL ? – Kiran Apr 12 '13 at 10:39
  • @Kiran: You can use depends.exe, it should show the calling convention. On the other hand, there only are a couple of them anyway, so you just might try them all. Start with cdcel. – Daniel Hilgarth Apr 12 '13 at 10:40
  • When I use CallingConvention = CallingConvention.Cdecl it processes the code and then the console closes by itself. it even don't come to debug point – Kiran Apr 12 '13 at 10:44
  • CallingConvention.Cdecl = Console closes by itself (code does not go to debug point) CallingConvention.FastCall = Invalid unmanaged calling convention: must be one of stdcall, cdecl, or thiscall. CallingConvention.stdcall = This is the default I was using and it gives me error which is mentioned in my post CallingConvention.thiscall = Exception External component has thrown an exception. – Kiran Apr 12 '13 at 10:48
  • break point is after line iResult = ProcessFilesC( ... where I use console.writeline – Kiran Apr 12 '13 at 10:50
  • @Kiran: In that case, the problem most likely lies elsewhere. Maybe you have to pin any of the variables you pass to the method. – Daniel Hilgarth Apr 12 '13 at 10:53
  • I am totally hanged here. Can you just tell me that the parameters which I have passed are correct or not ? – Kiran Apr 12 '13 at 11:38