C# wrapper for importing .dll, "Attempted to read or write protected memory"
.net, c#, dll, pinvoke, vb6
Solution
The sample VB program you gave:
Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long
Doesn't say `ByVal`. The default in VB is `ByRef`. Is this a typo on your part or is that the problem? If so you need to say `ref Byte` in your signature to SerialNumber.
Moral: Always say `ByRef` or `ByVal`.
Problem
After a mountain of research and experimentation, I still can't figure out an issue I'm having with accessing un-managed functions from an external library. Quick relevant backstory: I wrote an application in Visual C++ to drive an external meter that connects to the system through USB, but is virtualizing a serial port, and I was noticing weird output behavior. In order to vindicate themselves, the manufacturer wants me to use their .dll to control the meter from my application. Fine, but.... I wasn't able to include this .dll directly as a reference (name & path removed): So In order to use it, I presumably looked to DllImport. Instead of including the code directly into my application, I decided to make my own assembly as a wrapper for the driver so I could access the functionality through a class. After doing a dumpbin /exports on the .dll, I found the entry points for all the functions and made a C# class library like so, with only the relevant examples included: ``` namespace Meter { public class PortDrv { [DllImport("PortDrv.dll", EntryPoint = "SERIALNUMBER", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)] public static extern long SerialNumber(Byte Index); [DllImport("PortDrv.dll", EntryPoint = "OPENPORT", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)] public static extern int OpenPort(); }; } ``` The function prototypes were pulled from the .pdf they sent me describing their library: ``` SERIALNUMBER (ByVal Index As Byte) As Long OPENPORT () As Integer ``` And is also used in their sample VB program: ``` Private Declare Function SerialNumber Lib "PortDrv" Alias "SERIALNUMBER" (Index As Byte) As Long Private Declare Function OpenPort Lib "PortDrv" Alias "OPENPORT" () As Integer ``` Still with me? Ok. So after compiling my own assembly, I added the reference to my application and accessed the wrapper as such: ``` int port_return = PortDrv::OpenPort(); Byte bite = 0x31; __int64 serial = PortDrv::SerialNumber(bite); ``` But it bombs after trying to retrieve the serial number: And I'm not quite sure where I'm going wrong. Some of the functions return correct information, but it appears any that I have to pass information to fail. I've tried all different combinations of CharSets & CallingConventions, I've set the ExactSpelling to true, etc. Is there anything glaringly obvious that I'm doing wrong, or can I just not use this library in my current environment? EDIT: I forgot to mention that, the reason I pass '1' into the function is that, if there is only one meter connected to the system, the "Index" would be 1. If there were 2 meters, I could access the second one by passing in '2'.