I have been attempting to get the MySQL Embedded Library working in my C# application for the past 12 hours or so, and have been stuck for quite some time. I am getting the following error when I call mysql_server_init()
...
Unhandled Exception: System.AcessViolationException: Attempted to read or write protected memory.
The C++ method takes an int
and two char**
as parameters, but I was told a null terminated string[]
array would suffice in C#. As this is the first method that you're supposed to call, I am somewhat at a loss as to this issue.
Here's my code...
public class MySQLServer
{
[DllImport("libmysqld.dll")]
static extern int mysql_server_init(int argc, string[] argv, string[] groups);
[DllImport("libmysqld.dll")]
static extern void mysql_server_end();
public static bool Start()
{
string[] argv = new string[3];
argv[0] = "mysql_test";
argv[1] = "--datadir=C:/MYSQLTEST";
argv[2] = null;
string[] groups = new string[3];
groups[0] = "libmysqd_server";
groups[1] = "libmysqd_client";
groups[2] = null;
int res;
if ((res = mysql_server_init(3, argv, groups)) == 1)
{
Console.WriteLine("MySQL Library Init Failed with error code: %d", res);
return false;
}
Console.WriteLine("MySQL Library Started Successfully!");
return true;
}
}
It seems to me that you have a tiny error, causing
mysql_server_init
to read beyond the array boundaries. Replace3
with2
and remove the third array entry. The default marshaler will do the rest.Update
From this thread, you should not use
mysql_server_init
at all, butmysql_library_init
instead:So, if you can switch to using
mysql_library_init
, I'd suggest doing so. By-hand marshaling is not a trivial undertaking (but not too hard either).Who exactly told you this?
I do believe you could just use a reference to a char[]
Be sure the calling convention matches otherwise you will run into issues.
Mitch Wheat's answer can be enchanced by this thread: Marshalling a char** in C#
Some Additional Information: C# Marshalling char** and unsigned char**
If the strings are being read from, you should be able to pass as an array of strings.
If they are being written to, then you will have to declare the parameters as
IntPtrs
, allocate the memory for them, and then marshal the data yourself (plus you will need to unallocate the memory as well).what happens if you call like so (argc := 2):