1

I have a C++ dll which is used to card printing( ID cards ). My implementation done using C#.Net. I used following code to call c++ dll.

[DllImport(@"J230i.dll",CallingConvention = CallingConvention.Cdecl,SetLastError=true)]
public static extern int N_PrintJobStatus(ref int[] nPrtintjobStatus);

int[] pJob = {0,0,0,0,0,0,0,0} ;

ret = N_PrintJobStatus( ref pJob);

N_PrintJobStatus method signature given as bellow

N_PrintJobStatus(int *pJobStatus )

After calling the method it gives following error

A call to PInvoke function '********!*********.frmCardPrint::N_PrintJobStatus' 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.

How can I fix this issue

thank you .....

1 Answer 1

4

Your translation is incorrect. An int array, int* does not map to ref int[]. The latter would be marshalled as int**. You need instead to use int[].

[DllImport(@"J230i.dll", CallingConvention = CallingConvention.Cdecl, 
    SetLastError = true)]
public static extern int N_PrintJobStatus(int[] nPrtintjobStatus);

Allocate the array before calling the function. Presumably you have some way to determine how long it should be. As it stands this function looks like a buffer overrun waiting to happen. How can the function know how long the array is and so take steps to avoid writing beyond its end?

It's not clear that this is the only problem. We cannot be sure that the return type really is int. Or that the calling convention is cdecl. Or that the function really does call SetLastError.

Sign up to request clarification or add additional context in comments.

5 Comments

I have the exact same problem. But this solution didn't work. Still getting AccessViolationException
@SZT Perhaps it wasn't exactly the same problem. Because C# int[] does match C++ int*, assuming that the C++ code accepts an array. Then again, perhaps the C++ code returns a single int, in which case out int would be appropriate.
In my case the method looks like this: int __stdcall PrintColumn(LPSTR szHeader, int nNumColumns, LPINT nC, LPINT noC). After googling around I found LPINT is same as int* but passing an int[] still throws exception
@SZT is nC a pointer to a single integer, or an array?
@SZT then int[] is fine. The problem is elsewhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.