Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / November 2006

Tip: Looking for answers? Try searching our database.

calling a DLL-function from .NET including a function pointer within a class/structure

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
ms - 22 Nov 2006 12:03 GMT
Hello all,
i have problems to implement a structure including a callback function
pointer correctly in C# .NET.
The structure is used as a parameter for a initializing function, which
is implemented in a C++ dll (unmanaged code) i want to use.

THEME: calling a DLL-function from .NET including a function pointer
within a class/structure - interop / marshal

First i made a declaration for the function:

        [DllImport("mydll.dll", CharSet = CharSet.Ansi)]
        private static extern System.Int32 Initialize(ref PARAM para);

        //in the dll-documentation it is declared like this. long must now be
a int, the datatypes increased in .NET
        //long Initialize( PARAM *para );

        // and the structure is originally
       //typedef struct
       //{
       //    DWORD   MacNo;
       //    DWORD   OwnPort;
       //    DWORD   IpAddr;
       //    DWORD   Port;
       //    VOID (*CallBack)(DWORD, DWORD, VOID *);
                                   /* Call back routine */
       //    WORD    Timeout[20];
       //    WORD    retry[20];
       //} PARAM ;

then i defined the structure in my code as follows:

        [StructLayout(LayoutKind.Sequential)]
            public class PARAM
        {
            public System.Int32 nMacNo;
            public System.Int32 nOwnPort;
            public System.Int32 nIpAddr;
            public System.Int32 nNCPort;

            [MarshalAsAttribute(UnmanagedType.FunctionPtr)]
            public CallbackFunctionHandler cb;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst=PARA_ARR_LEN)]
            public System.Int16[] arrTimeout = new System.Int16[PARA_ARR_LEN];

            [MarshalAs(UnmanagedType.ByValArray, SizeConst=PARA_ARR_LEN)]
            public System.Int16[] arrRetry = new System.Int16[PARA_ARR_LEN];
        }

and i created a delegate as a funtion pointer:

         // member
        public delegate void CallbackFunctionHandler(System.UInt32 iHandle,
System.UInt32 iEvent, IntPtr arg);
        CallbackFunctionHandler callBackFunctionHandler = new
CallbackFunctionHandler(CallBack);

later on in my code i fill the structure with values and try to call
the initialize function

    // PARAM para = new PARAM(); member
    para.cb = callBackFunctionHandler;
    //...and all other values

    // call the function seems not be ok, but i get no error
    int nResult = Initialize(ref para);

    // and the function which should be called if data arrived
    public static void CallBack(System.UInt32 iHandle, System.UInt32
iEvent, IntPtr arg)

I've tried now so many things and attributes, also with keyword
"unsafe", but i don't get it to work, the tread within the dll is not
started after invoking the initialize function.
It would be nice to know how a callback function pointer must be
marshalled to the unmanaged dll.
Any help would be appreciated.
Martin
Marcus Heege - 22 Nov 2006 14:18 GMT
At the first quick view, your code seems ok. What exactly is goin wrong?
What is the calling convention of CallBack?

Marcus

> Hello all,
> i have problems to implement a structure including a callback function
[quoted text clipped - 76 lines]
> Any help would be appreciated.
> Martin
ms - 24 Nov 2006 15:32 GMT
I found a solution now, but i don't have enough time to write it down
now.
I'll post it on monday or thuesday. Thanks.
ms - 27 Nov 2006 10:02 GMT
i had two problems with this code.
1) the callback-function was never called
2) at the end of the callback-function the program crashed

the solutions are rather simple
1) i changed 'class' PARAM to 'struct', or replace 'ref' with '[In]' in
Initialize function declaration. Using a 'ref class' passes double
reference (PARAM**), because class is already passed by reference
(unlike the struct, which is by default passed by value).
And i removed array initializers from the structure.

2) there was a stack corruption, because of __cdecl calling convention
of the callback function. There are several ways to solve this issue:
a) force library vendor to use __stdcall modifier for callbacks. This
would be best, but also very unlikely to happen.
b) use a wrapper library written in C++, which will provide
"translation" layer for the callbacks. You'll need header and .lib file
for the dll.
c) use a wrapper library written in managed C++. This is similar to b),
but it can provide better .NET-friendly interface, which may avoid the
need of interop code in the application.
d) manually add the cdecl modopt modifier to disassembled IL source and
re-compile it. This has to be done after each build, for example as a
part of post-build step, text manipulation can be automated. There are
some examples on the Internet...
e) switch to Visual Studio 2005. I've found (but not yet tested)
UnmanagedFunctionPointer attribute which can be used to mark a delegate
with cdecl calling convention

I decided to write a wrapper library in C++ (solution b) which i use
now for calling a "__stdcall Initialize"-function.
Hope this helps anybody out there.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.