473,405 Members | 2,279 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

PInvoke with callback & function pointers: struct or class?

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:

MarshalDirectiveException
Method's type signature is not PInvoke compatible.

I then changed the structs to classes but now I get the following error:

AccessViolationException
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(int major_version, int minor_version, RtcInitParams *initParams);

typedef struct DLL_FUNCTION {
char* configPath;
RtcLogMode logMode;
const char* logPath;
void (*rtcOnLog)(const char *logMessage);
} RtcInitParams;

typedef struct DLL_FUNCTION {
int (*getUser)(char *userId, int len);
int (*setUser)(const char *userId, const char *password);
int (*getProxyServerAddresses)(char *addresses, int len);
int (*setProxyServerAddresses)(const char *addresses);
int (*getLocalIPAddress)(char *localIf, int len);
int (*setLocalIPAddress)(const char *localIp);
int (*findActiveLocalIPAddress)(char *activeIPAddress, int len);
int (*getLocalMediaAddress)(char *localMediaIf, int len);
int (*setLocalMediaAddress)(const char *localMediaIp);
int (*getSipPort)(int *port);
int (*setSipPort)(int port);
int (*getHttpProxySettings)(int *autoDetect, int *direct, char *addr, int addrLen, char *script, int scriptLen, char *cred, int credLen);
int (*setHttpProxyDirect)();
int (*setHttpProxyAutoDetect)();
int (*setHttpProxyAddress)(const char *addr);
int (*setHttpProxyPAC)(const char *pacAddr);
int (*setHttpProxyCredentials)(const char *user, const char *password);
int (*getAlwaysTunnelMedia)(int *alwaysTunnel);
int (*setAlwaysTunnelMedia)(int alwaysTunnel);
int (*getSignalingMode)(RtcSignalingMode *mode);
int (*setSignalingMode)(RtcSignalingMode mode);
int (*getLocalTunnelPort)(int *tunnelPort);
int (*getFirewallType)(char *fwType, int len);
int (*setSignalHandlerMask)(RtcSignalMask mask);
int (*setLogLevel)(RtcLogLevel logLevel);
int (*setLogGroups)(const char* groups);
int (*getVersion)(char *version, int len);
int (*getIceEnabled)(int* enable);
int (*setIceEnabled)(int enable);
int (*getStunEnabled)(int* enable);
int (*setStunEnabled)(int enable);
int (*getTurnEnabled)(int* enable);
int (*setTurnEnabled)(int enable);
int (*getStunServerAddresses)(char *addresses, int len);
int (*setStunServerAddresses)(const char *addresses);
int (*getTurnServerAddresses)(char *addresses, int len);
int (*setTurnServerAddresses)(const char *addresses);
int (*setSocksEnabled)(int enable);
int (*setSocksAddress)(char* addr, int port);
int (*getSocksAddress)(char* addr, int addrLen, int* port);
int (*closeLogFileAbnormally)(char* logfilename, int len);
} RtcConfigHandle;

which I have translated as:

[DllImport("rtcSdk.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern RtcConfigHandle RtcInitialize(int major_version, int minor_version, ref RtcInitParams initParams);

[StructLayout(LayoutKind.Sequential, Pack=4)]
private struct RtcInitParams
{
public string configPath;
public RtcLogMode logMode; // this is an enum
public string logPath;
[MarshalAs(UnmanagedType.FunctionPtr)]
public rtcOnLogDelegate rtcOnLog;
}


[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct RtcConfigHandle
{
[MarshalAs(UnmanagedType.FunctionPtr)]
public getUserDelegate getUser;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setUserDelegate setUser;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getProxyServerAddressesDelegate getProxyServerAddresses;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setProxyServerAddressesDelegate setProxyServerAddresses;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getLocalIPAddressDelegate getLocalIPAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setLocalIPAddressDelegate setLocalIPAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public findActiveLocalIPAddressDelegate findActiveLocalIPAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getLocalMediaAddressDelegate getLocalMediaAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setLocalMediaAddressDelegate setLocalMediaAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getSipPortDelegate getSipPort;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setSipPortDelegate setSipPort;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getHttpProxySettingsDelegate getHttpProxySettings;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setHttpProxyDirectDelegate setHttpProxyDirect;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setHttpProxyAutoDetectDelegate setHttpProxyAutoDetect;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setHttpProxyAddressDelegate setHttpProxyAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setHttpProxyPACDelegate setHttpProxyPAC;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setHttpProxyCredentialsDelegate setHttpProxyCredentials;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getAlwaysTunnelMediaDelegate getAlwaysTunnelMedia;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setAlwaysTunnelMediaDelegate setAlwaysTunnelMedia;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getSignalingModeDelegate getSignalingMode;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setSignalingModeDelegate setSignalingMode;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getLocalTunnelPortDelegate getLocalTunnelPort;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getFirewallTypeDelegate getFirewallType;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setSignalHandlerMaskDelegate setSignalHandlerMask;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setLogLevelDelegate setLogLevel;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setLogGroupsDelegate setLogGroups;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getVersionDelegate getVersion;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getIceEnabledDelegate getIceEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setIceEnabledDelegate setIceEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getStunEnabledDelegate getStunEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setStunEnabledDelegate setStunEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getTurnEnabledDelegate getTurnEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setTurnEnabledDelegate setTurnEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getStunServerAddressesDelegate getStunServerAddresses;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setStunServerAddressesDelegate setStunServerAddresses;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getTurnServerAddressesDelegate getTurnServerAddresses;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setTurnServerAddressesDelegate setTurnServerAddresses;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setSocksEnabledDelegate setSocksEnabled;
[MarshalAs(UnmanagedType.FunctionPtr)]
public setSocksAddressDelegate setSocksAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public getSocksAddressDelegate getSocksAddress;
[MarshalAs(UnmanagedType.FunctionPtr)]
public closeLogFileAbnormallyDelegate closeLogFileAbnormally;
}

private delegate void rtcOnLogDelegate(string logMessage);
private delegate int getStatusDelegate(ref RtcEventState state);
private delegate int rtcStopDelegate();
private delegate int rtcLockDelegate();
private delegate int rtcUnlockDelegate();
private delegate int rtcIsLockedDelegate(ref int locked);
private delegate void rtcOnEventDelegate(IntPtr userdata, RtcEventState state, RtcEventSubState substate, string substateDescription);
private delegate int getUserDelegate(ref string userId, int len);
private delegate int setUserDelegate(string userId, string password);
private delegate int getProxyServerAddressesDelegate(ref string addresses, int len);
private delegate int setProxyServerAddressesDelegate(string addresses);
private delegate int getLocalIPAddressDelegate(ref string localIf, int len);
private delegate int setLocalIPAddressDelegate(string localIp);
private delegate int findActiveLocalIPAddressDelegate(ref string activeIPAddress, int len);
private delegate int getLocalMediaAddressDelegate(ref string localMediaIf, int len);
private delegate int setLocalMediaAddressDelegate(string localMediaIp);
private delegate int getSipPortDelegate(ref int port);
private delegate int setSipPortDelegate(int port);
private delegate int getHttpProxySettingsDelegate(ref int autoDetect, ref int direct, ref string addr, int addrLen, ref string script, int scriptLen, ref string cred, int credLen);
private delegate int setHttpProxyDirectDelegate();
private delegate int setHttpProxyAutoDetectDelegate();
private delegate int setHttpProxyAddressDelegate(string addr);
private delegate int setHttpProxyPACDelegate(string pacAddr);
private delegate int setHttpProxyCredentialsDelegate(string user, string password);
private delegate int getAlwaysTunnelMediaDelegate(ref int alwaysTunnel);
private delegate int setAlwaysTunnelMediaDelegate(int alwaysTunnel);
private delegate int getSignalingModeDelegate(ref RtcSignalingMode mode);
private delegate int setSignalingModeDelegate(RtcSignalingMode mode);
private delegate int getLocalTunnelPortDelegate(ref int tunnelPort);
private delegate int getFirewallTypeDelegate(ref string fwType, int len);
private delegate int setSignalHandlerMaskDelegate(RtcSignalMask mask);
private delegate int setLogLevelDelegate(RtcLogLevel logLevel);
private delegate int setLogGroupsDelegate(string groups);
private delegate int getVersionDelegate(ref string version, int len);
private delegate int getIceEnabledDelegate(ref int enable);
private delegate int setIceEnabledDelegate(int enable);
private delegate int getStunEnabledDelegate(ref int enable);
private delegate int setStunEnabledDelegate(int enable);
private delegate int getTurnEnabledDelegate(ref int enable);
private delegate int setTurnEnabledDelegate(int enable);
private delegate int getStunServerAddressesDelegate(ref string addresses, int len);
private delegate int setStunServerAddressesDelegate(string addresses);
private delegate int getTurnServerAddressesDelegate(ref string addresses, int len);
private delegate int setTurnServerAddressesDelegate(string addresses);
private delegate int setSocksEnabledDelegate(int enable);
private delegate int setSocksAddressDelegate(ref string addr, int port);
private delegate int getSocksAddressDelegate(ref string addr, int addrLen, ref int port);
private delegate int closeLogFileAbnormallyDelegate(ref string logfilename, int len);
Feb 25 '08 #1
1 6609
Strange how you see a way forward within minutes of posting a question...

I changed the return type of the methods to IntPtr and then used Marshal.PtrToStructure to get back to the managed struct.

Although I haven't completed this work, it seems to be holding together now.

Stuart


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:

MarshalDirectiveException
Method's type signature is not PInvoke compatible.

I then changed the structs to classes but now I get the following error:

AccessViolationException
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
Feb 25 '08 #2

Sign in to post your reply or Sign up for a free account.

Similar topics

0
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion is as follows **************************************** The Original Fucntion in the dll...
0
by: vijaya | last post by:
I've a problem with PInvoke.I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.Please apologise for this lenghty message and render ur kind help. The original dll...
2
by: MR | last post by:
help! I have an unmanaged DLL that I do not have the source code, so i can't recompile or make changes. the DLL requires a callback function. I would like to implement the callback method in a...
6
by: Pucca | last post by:
I have a program that originally compiles into a exe file. I changed the compile option to generate dll file. This program calls a com component. Can I use pinvoke in C# to call it? The...
4
by: Kyku | last post by:
Hello all, I'm in a process of writing a small Linux C++ program for discovering repeaded files over a filesystem. One part of this task is traversing a directory structure. This is done by the...
2
by: MyCrystalGift | last post by:
Hi, I have an old C++ GUI Application CPPAPP.exe that calls a C DLL library RULE.DLL through a C++ class wrapper LoadRule.CPP. Now I need to call the C DLL RULE.DLL from C# GUI application...
6
by: gregarican | last post by:
I am trying to port a legacy CTI application written in another programming language to C# 2005. From my initial research into it I see I can utilize the DllImport method to tap into the DLL file...
14
by: Mohamed Mansour | last post by:
Hey there, this will be somewhat a long post, but any response is appreciated! I have done many PInvoke in the past from C++ to C#, but I did PInvoke within C# not C++/CLI. Can someone explain...
0
by: Michibeck | last post by:
Hi, I need some help regarding callback function written in c# and called from unmanaged c code. (c dll). The problem is that the callback function crashs after the first call with a memory...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.