473,322 Members | 1,610 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,322 software developers and data experts.

Callbacks from unmanaged code...

Hi there,

I'm new to C# (but not to C++), and I'm trying to create a web service that
calls some of our older software, located in a DLL. I'm getting most the
calls to work ok, but one of them needs a callback into the managed code. I
thought I had it all worked out, but it seems like when the callback is
getting hit, things might be going out of scope and crashing the app.

Here's my little web service function; I hacked out a bunch of other stuff
for brevity, but the general idea is, I call the "Initialize" function,
providing a callback to the DLL so the DLL can call me when certain
operations in the "LoginUser2" complete.

You can see where I tried to keep the callback around in a session object,
but, being a novice, I'm not sure this is the right approach. Essentially, I
need this callback alive for the whole life of the user's session.

[WebMethod(EnableSession = true)]
public string HelloArguments(string sLogin, string sPassword)
{
Test.TNInitializeCallbackType cb = new
Test.TNInitializeCallbackType(Test.TNAPICallback);
Session["Callback"] = cb;

hWho = Test.Initialize(cb);

result2 = Test.LogonUser2(hWho, sLogin, sPassword);

return sResult;
}

and some defs:

class Test
{
[DllImport("mydll.dll")]
public static extern Int32 LogonUser2(IntPtr hWho, string pszLogin,
string pszPassword);

public delegate IntPtr TNInitializeCallbackType(IntPtr hWho, Int32
a1, Int32 a2, Int32 a3);

[DllImport("mydll.dll")]
public static extern IntPtr Initialize(TNInitializeCallbackType
callback);

public static IntPtr TNAPICallback(IntPtr hWho, Int32 a1, Int32 a2,
Int32 a3)
{
return (IntPtr)0;
}

Thanks for any help or pointers as to where I can read up on this.

Apr 11 '06 #1
2 2083
In .NET, the calling convention for methods is StdCall. What is the calling
convention for your unmanaged *.dll? I'm assumming it is probably cdecl,
which will cause problems in your managed callback. The stack is probably
being popped one too many times after your call back executes.

You can use the CallingConvention property of the DllImport attribute to
define the calling convention for that method, but I'm not sure if this can
be applied to delegates.

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl )]
public static extern IntPtr Initialize(TNInitializeCallbackType callback);

Not sure if the above code will work for a delegate, but you can give it a
shot. If you have the unmanaged souce code, you can probably create another
method called something like "InitializeStdCall" using the StdCall calling
convention and then in there, call "Initialize". This will act as a wrapper.

Hope this helps or points you in the right direction.

"cada0310" wrote:
Hi there,

I'm new to C# (but not to C++), and I'm trying to create a web service that
calls some of our older software, located in a DLL. I'm getting most the
calls to work ok, but one of them needs a callback into the managed code. I
thought I had it all worked out, but it seems like when the callback is
getting hit, things might be going out of scope and crashing the app.

Here's my little web service function; I hacked out a bunch of other stuff
for brevity, but the general idea is, I call the "Initialize" function,
providing a callback to the DLL so the DLL can call me when certain
operations in the "LoginUser2" complete.

You can see where I tried to keep the callback around in a session object,
but, being a novice, I'm not sure this is the right approach. Essentially, I
need this callback alive for the whole life of the user's session.

[WebMethod(EnableSession = true)]
public string HelloArguments(string sLogin, string sPassword)
{
Test.TNInitializeCallbackType cb = new
Test.TNInitializeCallbackType(Test.TNAPICallback);
Session["Callback"] = cb;

hWho = Test.Initialize(cb);

result2 = Test.LogonUser2(hWho, sLogin, sPassword);

return sResult;
}

and some defs:

class Test
{
[DllImport("mydll.dll")]
public static extern Int32 LogonUser2(IntPtr hWho, string pszLogin,
string pszPassword);

public delegate IntPtr TNInitializeCallbackType(IntPtr hWho, Int32
a1, Int32 a2, Int32 a3);

[DllImport("mydll.dll")]
public static extern IntPtr Initialize(TNInitializeCallbackType
callback);

public static IntPtr TNAPICallback(IntPtr hWho, Int32 a1, Int32 a2,
Int32 a3)
{
return (IntPtr)0;
}

Thanks for any help or pointers as to where I can read up on this.

Apr 12 '06 #2
Hi - thanks for your response!

The definition is actually __stdcall in the unmanaged code; here's the C++
prototype definition for the callback that has to be passed to C++:

typedef long (*TNAPI_CALLBACK)(HANDLE, DWORD, DWORD, DWORD);
HANDLE CALLBACK TN_Initialize(TNAPI_CALLBACK pFunc);

So the idea is that in C# I need to call TN_Initilalize and pass it a
callback function, so that the unmanaged DLL can make calls to the provided
callback.

It seems to be (mostly) working; I can set breakpoints in the C# provided
callback, and it's getting called...but I think something's munged because
sometimes the app just croaks.
"rmacias" wrote:
In .NET, the calling convention for methods is StdCall. What is the calling
convention for your unmanaged *.dll? I'm assumming it is probably cdecl,
which will cause problems in your managed callback. The stack is probably
being popped one too many times after your call back executes.

You can use the CallingConvention property of the DllImport attribute to
define the calling convention for that method, but I'm not sure if this can
be applied to delegates.

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl )]
public static extern IntPtr Initialize(TNInitializeCallbackType callback);

Not sure if the above code will work for a delegate, but you can give it a
shot. If you have the unmanaged souce code, you can probably create another
method called something like "InitializeStdCall" using the StdCall calling
convention and then in there, call "Initialize". This will act as a wrapper.

Hope this helps or points you in the right direction.

"cada0310" wrote:
Hi there,

I'm new to C# (but not to C++), and I'm trying to create a web service that
calls some of our older software, located in a DLL. I'm getting most the
calls to work ok, but one of them needs a callback into the managed code. I
thought I had it all worked out, but it seems like when the callback is
getting hit, things might be going out of scope and crashing the app.

Here's my little web service function; I hacked out a bunch of other stuff
for brevity, but the general idea is, I call the "Initialize" function,
providing a callback to the DLL so the DLL can call me when certain
operations in the "LoginUser2" complete.

You can see where I tried to keep the callback around in a session object,
but, being a novice, I'm not sure this is the right approach. Essentially, I
need this callback alive for the whole life of the user's session.

[WebMethod(EnableSession = true)]
public string HelloArguments(string sLogin, string sPassword)
{
Test.TNInitializeCallbackType cb = new
Test.TNInitializeCallbackType(Test.TNAPICallback);
Session["Callback"] = cb;

hWho = Test.Initialize(cb);

result2 = Test.LogonUser2(hWho, sLogin, sPassword);

return sResult;
}

and some defs:

class Test
{
[DllImport("mydll.dll")]
public static extern Int32 LogonUser2(IntPtr hWho, string pszLogin,
string pszPassword);

public delegate IntPtr TNInitializeCallbackType(IntPtr hWho, Int32
a1, Int32 a2, Int32 a3);

[DllImport("mydll.dll")]
public static extern IntPtr Initialize(TNInitializeCallbackType
callback);

public static IntPtr TNAPICallback(IntPtr hWho, Int32 a1, Int32 a2,
Int32 a3)
{
return (IntPtr)0;
}

Thanks for any help or pointers as to where I can read up on this.

Apr 12 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion returns a pointer to a structure to its callback fucntion.The user should collect those...
1
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion returns a pointer to a structure to its callback fucntion.The user should collect those...
23
by: Brian | last post by:
I am very new to C# programming and have run into a problem. I apologize for the repost of this article. For some reason, my news reader attached it to an existing thread. First off, I have...
4
by: R. MacDonald | last post by:
Hello, all, I have a .NET application (VB) that passes the address of a delegate to unmanaged code in a DLL. The unmanaged code then uses the delegate as a call-back. This seems to work...
6
by: per9000 | last post by:
An interesting/annoying problem. I created a small example to provoke an exception I keep getting. Basically I have a C-struct (Container) with a function-pointer in it. I perform repeated calls...
3
by: kelvin.koogan | last post by:
I have an unmanaged DLL which calls my managed C++ app using a callback (standard C++ function pointer). I can receive the callbacks OK using a static function with global scope, but I can't find a...
8
by: DavidT | last post by:
Hello, at first, exuse if the following question is simple to solve, but i normaly coding with C# and now have to use C++/CLI for one project. My Problem is that i have to use a native c++ sdk...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.