Click here to Skip to main content
15,889,176 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,
I have problem with invoking my c++ dll into c# code. The problem is when one of c++ dll functions being called an error exception accord "System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.".
I don't have any idea what is that mean.

This is c++ dll function:

C++
extern "C" __declspec(dllexport) int ScanFile(string filename, int sigc, int hashc, string sigs[], string hashs[]);

Scanner scan;

int ScanFile(string filename, int sigc, int hashc, string sigs[], string hashs[])
{
	int x;
	for(x = 0; x < sigc; x++)
		scan.sigs.push_back(sigs[x]);
	for(x = 0; x < hashc; x++)
		scan.hashs.push_back(hashs[x]);
	int result = scan.ScanFile(filename);
	if(result == 0) { if (scan.fileScanResult.IsVirus) result = 1; }
	else result ++;
	return result;
}


And this is c# code calling that function:

C#
//in NativeMethods class
        [DllImport("slib.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ScanFile(string filename, int sigc, int hashc, string[] sigs, string[] hashs);

public struct FileScanResult
        {
            public string FileName;
            public bool IsVirus;
            public int result;
        }
//in another class
        public static FileScanResult ScanFile(string Path, string[] Sigs, string[] Hashs)
        {
            int r = NativeMethods.ScanFile(Path, Sigs.Length, Hashs.Length, Sigs, Hashs); //Here is the error

            FileScanResult result = new FileScanResult();
            if (r == 0) { result.result = r; result.FileName = Path; result.IsVirus = false; }
            if (r == 1) { result.result = r; result.FileName = Path; result.IsVirus = true; }
            if (r == 2) { result.result = r; result.FileName = Path; result.IsVirus = false; }
            if (r == 3) { result.result = r; result.FileName = Path; result.IsVirus = false; }
            return result;
        }
Posted

1 solution

You're probably mixing managed (C#) and unmanaged (C++) code.
You have to use Marshal[^] class to copy memory and convert types from and to managed enviroment.

Marshaling with C# – Chapter 2: Marshaling Simple Types[^]
Marshaling with C# – Chapter 3: Marshaling Compound Types[^]

How to Marshal a C++ Class[^] (solution B)
 
Share this answer
 
v2
Comments
[no name] 9-Mar-13 1:42am    
I have read the documentation. But I don't understand what managed and unmanaged code means?
Do you have extra resources to understand why this error happens to me, what is managed and unmanaged code means, and memory management (advanced explanation because I know some basics of memory management)?
There is alot of things that must know.
sjelen 11-Mar-13 8:07am    
Managed code runs inside CLR (Common Language Runtime) which has it's own memory management including a garbage collector.
Unmanaged code runs directly on top of OS (no runtime enviroment, no garbage collector).

Unmanaged code can't access managed memory directly (I guess that's the error you're getting). You need to copy data from managed memory to unmanaged memory and use that copy as parameter to unmanaged method. The result from unmanaged method also has to be copied back to managed memory before it can be used by managed code.
This process is called marshaling and Marshal class has many methods to make this easier.
In some cases can also be done by using 'MarshalAs' attribute on parameters and return type.
Take a look at articles I added above.
[no name] 9-Mar-13 1:47am    
The second thing, I didn't see any solution for my error in Marshal class. The following code shows only that to call the invoked function and get error code if failed:
// Demonstrate how to use the Marshal class to get the Win32 error
// code when a Win32 method fails.
Boolean f = CloseHandle(new IntPtr(-1));
if (!f)
{
Console.WriteLine("CloseHandle call failed with an error code of: {0}",
Marshal.GetLastWin32Error());
}

this don't solve my problem

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900