I need to use an unmanaged c++ dll which uses structs that contain callbacks and also functions. I have included the appropriate c++ definitials and my c# translations below.
I first defined the parameters as c# structs, but when I tried the call (to RtcInitialize) I got the following error:
MarshalDirectiv eException
Method's type signature is not PInvoke compatible.
I then changed the structs to classes but now I get the following error:
AccessViolation Exception
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Can anyone see what I am doing wrong?
Thanks,
Stuart
The first c++ definitions are:
DLL_FUNCTION RtcConfigHandle * RtcInitialize(i nt major_version, int minor_version, RtcInitParams *initParams);
typedef struct DLL_FUNCTION {
char* configPath;
RtcLogMode logMode;
const char* logPath;
void (*rtcOnLog)(con st char *logMessage);
} RtcInitParams;
typedef struct DLL_FUNCTION {
int (*getUser)(char *userId, int len);
int (*setUser)(cons t char *userId, const char *password);
int (*getProxyServe rAddresses)(cha r *addresses, int len);
int (*setProxyServe rAddresses)(con st char *addresses);
int (*getLocalIPAdd ress)(char *localIf, int len);
int (*setLocalIPAdd ress)(const char *localIp);
int (*findActiveLoc alIPAddress)(ch ar *activeIPAddres s, int len);
int (*getLocalMedia Address)(char *localMediaIf, int len);
int (*setLocalMedia Address)(const char *localMediaIp);
int (*getSipPort)(i nt *port);
int (*setSipPort)(i nt port);
int (*getHttpProxyS ettings)(int *autoDetect, int *direct, char *addr, int addrLen, char *script, int scriptLen, char *cred, int credLen);
int (*setHttpProxyD irect)();
int (*setHttpProxyA utoDetect)();
int (*setHttpProxyA ddress)(const char *addr);
int (*setHttpProxyP AC)(const char *pacAddr);
int (*setHttpProxyC redentials)(con st char *user, const char *password);
int (*getAlwaysTunn elMedia)(int *alwaysTunnel);
int (*setAlwaysTunn elMedia)(int alwaysTunnel);
int (*getSignalingM ode)(RtcSignali ngMode *mode);
int (*setSignalingM ode)(RtcSignali ngMode mode);
int (*getLocalTunne lPort)(int *tunnelPort);
int (*getFirewallTy pe)(char *fwType, int len);
int (*setSignalHand lerMask)(RtcSig nalMask mask);
int (*setLogLevel)( RtcLogLevel logLevel);
int (*setLogGroups) (const char* groups);
int (*getVersion)(c har *version, int len);
int (*getIceEnabled )(int* enable);
int (*setIceEnabled )(int enable);
int (*getStunEnable d)(int* enable);
int (*setStunEnable d)(int enable);
int (*getTurnEnable d)(int* enable);
int (*setTurnEnable d)(int enable);
int (*getStunServer Addresses)(char *addresses, int len);
int (*setStunServer Addresses)(cons t char *addresses);
int (*getTurnServer Addresses)(char *addresses, int len);
int (*setTurnServer Addresses)(cons t char *addresses);
int (*setSocksEnabl ed)(int enable);
int (*setSocksAddre ss)(char* addr, int port);
int (*getSocksAddre ss)(char* addr, int addrLen, int* port);
int (*closeLogFileA bnormally)(char * logfilename, int len);
} RtcConfigHandle ;
which I have translated as:
[DllImport("rtcS dk.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConventi on = CallingConventi on.StdCall)]
private static extern RtcConfigHandle RtcInitialize(i nt major_version, int minor_version, ref RtcInitParams initParams);
[StructLayout(La youtKind.Sequen tial, Pack=4)]
private struct RtcInitParams
{
public string configPath;
public RtcLogMode logMode; // this is an enum
public string logPath;
[MarshalAs(Unman agedType.Functi onPtr)]
public rtcOnLogDelegat e rtcOnLog;
}
[StructLayout(La youtKind.Sequen tial, Pack = 4)]
private struct RtcConfigHandle
{
[MarshalAs(Unman agedType.Functi onPtr)]
public getUserDelegate getUser;
[MarshalAs(Unman agedType.Functi onPtr)]
public setUserDelegate setUser;
[MarshalAs(Unman agedType.Functi onPtr)]
public getProxyServerA ddressesDelegat e getProxyServerA ddresses;
[MarshalAs(Unman agedType.Functi onPtr)]
public setProxyServerA ddressesDelegat e setProxyServerA ddresses;
[MarshalAs(Unman agedType.Functi onPtr)]
public getLocalIPAddre ssDelegate getLocalIPAddre ss;
[MarshalAs(Unman agedType.Functi onPtr)]
public setLocalIPAddre ssDelegate setLocalIPAddre ss;
[MarshalAs(Unman agedType.Functi onPtr)]
public findActiveLocal IPAddressDelega te findActiveLocal IPAddress;
[MarshalAs(Unman agedType.Functi onPtr)]
public getLocalMediaAd dressDelegate getLocalMediaAd dress;
[MarshalAs(Unman agedType.Functi onPtr)]
public setLocalMediaAd dressDelegate setLocalMediaAd dress;
[MarshalAs(Unman agedType.Functi onPtr)]
public getSipPortDeleg ate getSipPort;
[MarshalAs(Unman agedType.Functi onPtr)]
public setSipPortDeleg ate setSipPort;
[MarshalAs(Unman agedType.Functi onPtr)]
public getHttpProxySet tingsDelegate getHttpProxySet tings;
[MarshalAs(Unman agedType.Functi onPtr)]
public setHttpProxyDir ectDelegate setHttpProxyDir ect;
[MarshalAs(Unman agedType.Functi onPtr)]
public setHttpProxyAut oDetectDelegate setHttpProxyAut oDetect;
[MarshalAs(Unman agedType.Functi onPtr)]
public setHttpProxyAdd ressDelegate setHttpProxyAdd ress;
[MarshalAs(Unman agedType.Functi onPtr)]
public setHttpProxyPAC Delegate setHttpProxyPAC ;
[MarshalAs(Unman agedType.Functi onPtr)]
public setHttpProxyCre dentialsDelegat e setHttpProxyCre dentials;
[MarshalAs(Unman agedType.Functi onPtr)]
public getAlwaysTunnel MediaDelegate getAlwaysTunnel Media;
[MarshalAs(Unman agedType.Functi onPtr)]
public setAlwaysTunnel MediaDelegate setAlwaysTunnel Media;
[MarshalAs(Unman agedType.Functi onPtr)]
public getSignalingMod eDelegate getSignalingMod e;
[MarshalAs(Unman agedType.Functi onPtr)]
public setSignalingMod eDelegate setSignalingMod e;
[MarshalAs(Unman agedType.Functi onPtr)]
public getLocalTunnelP ortDelegate getLocalTunnelP ort;
[MarshalAs(Unman agedType.Functi onPtr)]
public getFirewallType Delegate getFirewallType ;
[MarshalAs(Unman agedType.Functi onPtr)]
public setSignalHandle rMaskDelegate setSignalHandle rMask;
[MarshalAs(Unman agedType.Functi onPtr)]
public setLogLevelDele gate setLogLevel;
[MarshalAs(Unman agedType.Functi onPtr)]
public setLogGroupsDel egate setLogGroups;
[MarshalAs(Unman agedType.Functi onPtr)]
public getVersionDeleg ate getVersion;
[MarshalAs(Unman agedType.Functi onPtr)]
public getIceEnabledDe legate getIceEnabled;
[MarshalAs(Unman agedType.Functi onPtr)]
public setIceEnabledDe legate setIceEnabled;
[MarshalAs(Unman agedType.Functi onPtr)]
public getStunEnabledD elegate getStunEnabled;
[MarshalAs(Unman agedType.Functi onPtr)]
public setStunEnabledD elegate setStunEnabled;
[MarshalAs(Unman agedType.Functi onPtr)]
public getTurnEnabledD elegate getTurnEnabled;
[MarshalAs(Unman agedType.Functi onPtr)]
public setTurnEnabledD elegate setTurnEnabled;
[MarshalAs(Unman agedType.Functi onPtr)]
public getStunServerAd dressesDelegate getStunServerAd dresses;
[MarshalAs(Unman agedType.Functi onPtr)]
public setStunServerAd dressesDelegate setStunServerAd dresses;
[MarshalAs(Unman agedType.Functi onPtr)]
public getTurnServerAd dressesDelegate getTurnServerAd dresses;
[MarshalAs(Unman agedType.Functi onPtr)]
public setTurnServerAd dressesDelegate setTurnServerAd dresses;
[MarshalAs(Unman agedType.Functi onPtr)]
public setSocksEnabled Delegate setSocksEnabled ;
[MarshalAs(Unman agedType.Functi onPtr)]
public setSocksAddress Delegate setSocksAddress ;
[MarshalAs(Unman agedType.Functi onPtr)]
public getSocksAddress Delegate getSocksAddress ;
[MarshalAs(Unman agedType.Functi onPtr)]
public closeLogFileAbn ormallyDelegate closeLogFileAbn ormally;
}
private delegate void rtcOnLogDelegat e(string logMessage);
private delegate int getStatusDelega te(ref RtcEventState state);
private delegate int rtcStopDelegate ();
private delegate int rtcLockDelegate ();
private delegate int rtcUnlockDelega te();
private delegate int rtcIsLockedDele gate(ref int locked);
private delegate void rtcOnEventDeleg ate(IntPtr userdata, RtcEventState state, RtcEventSubStat e substate, string substateDescrip tion);
private delegate int getUserDelegate (ref string userId, int len);
private delegate int setUserDelegate (string userId, string password);
private delegate int getProxyServerA ddressesDelegat e(ref string addresses, int len);
private delegate int setProxyServerA ddressesDelegat e(string addresses);
private delegate int getLocalIPAddre ssDelegate(ref string localIf, int len);
private delegate int setLocalIPAddre ssDelegate(stri ng localIp);
private delegate int findActiveLocal IPAddressDelega te(ref string activeIPAddress , int len);
private delegate int getLocalMediaAd dressDelegate(r ef string localMediaIf, int len);
private delegate int setLocalMediaAd dressDelegate(s tring localMediaIp);
private delegate int getSipPortDeleg ate(ref int port);
private delegate int setSipPortDeleg ate(int port);
private delegate int getHttpProxySet tingsDelegate(r ef int autoDetect, ref int direct, ref string addr, int addrLen, ref string script, int scriptLen, ref string cred, int credLen);
private delegate int setHttpProxyDir ectDelegate();
private delegate int setHttpProxyAut oDetectDelegate ();
private delegate int setHttpProxyAdd ressDelegate(st ring addr);
private delegate int setHttpProxyPAC Delegate(string pacAddr);
private delegate int setHttpProxyCre dentialsDelegat e(string user, string password);
private delegate int getAlwaysTunnel MediaDelegate(r ef int alwaysTunnel);
private delegate int setAlwaysTunnel MediaDelegate(i nt alwaysTunnel);
private delegate int getSignalingMod eDelegate(ref RtcSignalingMod e mode);
private delegate int setSignalingMod eDelegate(RtcSi gnalingMode mode);
private delegate int getLocalTunnelP ortDelegate(ref int tunnelPort);
private delegate int getFirewallType Delegate(ref string fwType, int len);
private delegate int setSignalHandle rMaskDelegate(R tcSignalMask mask);
private delegate int setLogLevelDele gate(RtcLogLeve l logLevel);
private delegate int setLogGroupsDel egate(string groups);
private delegate int getVersionDeleg ate(ref string version, int len);
private delegate int getIceEnabledDe legate(ref int enable);
private delegate int setIceEnabledDe legate(int enable);
private delegate int getStunEnabledD elegate(ref int enable);
private delegate int setStunEnabledD elegate(int enable);
private delegate int getTurnEnabledD elegate(ref int enable);
private delegate int setTurnEnabledD elegate(int enable);
private delegate int getStunServerAd dressesDelegate (ref string addresses, int len);
private delegate int setStunServerAd dressesDelegate (string addresses);
private delegate int getTurnServerAd dressesDelegate (ref string addresses, int len);
private delegate int setTurnServerAd dressesDelegate (string addresses);
private delegate int setSocksEnabled Delegate(int enable);
private delegate int setSocksAddress Delegate(ref string addr, int port);
private delegate int getSocksAddress Delegate(ref string addr, int addrLen, ref int port);
private delegate int closeLogFileAbn ormallyDelegate (ref string logfilename, int len);