Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple function calls from C# to C++ unmanaged code causes AccessViolationException

I have declared a DLL import in my C# program that looks like this:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
           CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type);

It references the function generateKeyCode() inside of my DLL.

Here is the code that is causing an error (used breakpoints):

const char* generateKeyCode(char serial[], 
                 char option[], 
                 char c_type)
{
returnBufferString = "";
SHA1_CTX context;
int optionLength = 0;
#ifdef WIN32
unsigned char buffer[16384] = {0};
#else
unsigned char buffer[256] = {0}; 

#endif
//char output[80];
char keycode[OPTION_KEY_LENGTH+1]        = "";
int digest_array_size = 10; //default value for digest array size
unsigned char digest[20] = {0};
char optx[24] = {0};
char c_type_upper;
// Combine serial # and Option or Version number

char str1[30] = {0};
int i;
int size = 0;
int pos = 0;


...
...
}

Basically, I imported this DLL so I could pass the function parameters and it could do its algorithm and simply return me a result. I used this marshaler function...

public static string genKeyCode_marshal(string serial, string option, char type)
{
    return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(), 
           option.ToCharArray(), type));
}

...so I could make the call properly. Inside of my C++ header file, I have defined a string, as indicated is helpful in the answer to this question (it is the returnBufferString variable present at the top of the C/C++ function).

I make this function call several times as I use a NumericUpDown control to go from 1.0 to 9.9 in increments of 0.1 (each up or down accompanies another function call), and then back down again. However, every time I try to do this, the program hitches after a seemingly set number of function calls (stops at 1.9 on the way back down if I just go straight up and down, or earlier if I alternate up and down a bit).

Please note that it works and gives me the value I want, there are no discrepancies there.

I changed the buffer size to some smaller number (5012) and when I tried to run the program, on the first function call it threw the AccessViolationException. However, doubling the buffer size to twice (32768) the original had no effect in comparison to the original -- going straight up to 9.9 from 1.0 and down back again, it stops at 1.9 and throws the exception.

EDIT: Default is ANSI, so it is ANSI. No problems there. Is this a memory allocation issue??

like image 324
Sean Glover Avatar asked Jan 04 '12 20:01

Sean Glover


People also ask

Can we have more than one function in C?

We know that the syntax of functions in C doesn't allow us to return multiple values. But programmers often need to return multiple values from a function.

Can you have multiple functions with the same name in C?

Function overloading is a feature of a programming language that allows one to have many functions with same name but with different signatures.

How many ways can C call function?

But for functions with arguments, we can call a function in two different ways, based on how we specify the arguments, and these two ways are: Call by Value. Call by Reference.


1 Answers

I would suggest trying the following:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
       CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr generateKeyCode(string serial, string option, char c_type);

Note the new CharSet field of DllImport attribute.

Next idea is to use MarshalAs attribute explicitely:

[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode", 
       CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
static extern IntPtr generateKeyCode([MarshalAs(UnmanagedType.LPTStr)] string serial, [MarshalAs(UnmanagedType.LPTStr)] string option, char c_type);
like image 107
Krizz Avatar answered Oct 19 '22 03:10

Krizz