0
votes

I am working on a project that requires implementing am unmanaged windows DLL. The DLL is used to communicate with a USB device. My code is in C# and WPF. To initialize the DLL I call a function called:

InitTimerDll(Int32 wHandle, ref dllInitParams initParams);

When calling this function I have to pass a struct called dllInitParams and the Handle that the control is bound to. I am using DllImport for function pointer as such:

[DllImport("myDll.dll")]
public static extern void InitTimerDll(Int32 wHandle, ref dllInitParams initParams);

Here is my struct:

public struct dllInitParams
{
    public UInt16 simp;

    public UInt16 simt;
}

All of the above are in a separate class called myDllInterface.cs. Here is how I call the InitTimerDll function from my WPF form:

public IntPtr Handle
{
    get { return (new System.Windows.Interop.WindowInteropHelper(this)).Handle; }
}

private void initTime_Click(object sender, RoutedEventArgs e)
{   
    myDllInterface.dllInitParams initParams = new myDllInterface.dllInitParams();
    initParams.simp = 0;
    myDllInterface.InitTimerDll(this.Handle.ToInt32(), ref initParams);
}

The first part of the above code explains how I get the handle and the initTime_Click shows how I initialize the struct, call the initTimeDll function by passing the handle and the struct to it. I have copied the dll file in the directory that the code runs in. My code compiles just fine but it creates an error when I click on the initTime button. Error:

An unhandled exception of type 'System.AccessViolationException' occurred in ProbeCTRL.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Why is this happening?

3
Hard to tell, the code that crashes isn't the code that you posted. You'll need to debug the native code. Project + Properties, Debug tab, tick "Enable unmanaged code debugging". Set a breakpoint on the InitTimerDll function in your C or C++ source code. - Hans Passant
Using an Int32 instead of IntPtr for handle values is probably going to cause problems in a 64-bit operating system. It's also possible your calling convention is wrong (The default in .NET is StdCall). - vcsjones

3 Answers

1
votes

Without knowing exactly what the InitTimerDll() function does with the 'this' pointer, I would focus on the params structure. Try adding a structure layout markup like the following:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct dllInitParams
{
    public UInt16 simp;
    public UInt16 simt;
}

Also, double check that your structure is complete and accurate.

1
votes

I found the problem. The code is fine the problem was the dll file, which was corrupted. A proper copy of the dll file took care of the problem. When using dll in your codes it is quite important to make sure you have accurate information, function calls, data types to passed and so on. Thanks everyone for your help.

0
votes

Have a look at the PInvoke tutorial: http://msdn.microsoft.com/en-us/library/aa288468%28v=vs.71%29.aspx

as Jim Gomes points out:

[StructLayout(LayoutKind.Sequential)]

or something similar is definitely important.

Also, you're only initializing one of the variables in your struct.