473,322 Members | 1,379 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.

Interoping CDecl callback on 1.1

Udi
Hi All,

I have a C dll exporting the following:
`````````````````````````````````````````````````` ``
typedef void (__cdecl *pCallBack)(int i);

int __cdecl Foo(pCallBack pFunc);
I have written an interop dll:
````````````````````````````````````````
public class FooInterop
{
public delegate void pCallBack(int i);

[DllImport("Foo.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int
Foo([MarshalAs(UnmanagedType.FunctionPtr)]pCallBack pFunc);
}

And I'm trying to call it this way:
```````````````````````````````````````````````

class Class1
{
[STAThread]
static void Main(string[] args)
{
int res = FooInterop.Foo(new FooInterop.pCallBack(Class1.FooCB));
Console.WriteLine(res);
}

static public void FooCB(int i)
{
Console.WriteLine(i);
}
}

For some reason when leaving FooCB I get the following error:

"Run-Time Check Failure #0 - The value of ESP was not properly saved
across a function call. This is usually a result of calling a
function declared with one calling convention with a function pointer
declared with a different calling convention."

I'm assuming this is because 'Foo' (in the C dll) is defined as
__cdecl and 'FooCB' (in .NET assembly) is an __stdcall. Am I right?
How do I tell the marsheler that C# method should behave as __cdecl
in .NET 1.1?
How do I solve this problem?
BTW defining the typedef as stdcall (I.e. typedef void (__stdcall
*pCallBack)(int i); )
works OK, but I'm not surethis is the solution I need.
Any ideas?
Thanks!

Mar 20 '07 #1
2 2904
Udi,

You can't do this in 1.1. In 2.0 and beyond, you would apply the
UnmanagedFunctionPointer attribute to the delegate parameter to indicate the
calling convention that the delegate should take on.

In .NET 1.1, you will have to create a shim which will take a function
pointer with the same signature (but not using the CDECL convention) and
returns a function pointer using the CDECL calling convention.

It's a bit of a hack, but your only option (unless you can change the
calling convention of the callback).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Udi" <Ud**********@gmail.comwrote in message
news:11**********************@e65g2000hsc.googlegr oups.com...
Hi All,

I have a C dll exporting the following:
`````````````````````````````````````````````````` ``
typedef void (__cdecl *pCallBack)(int i);

int __cdecl Foo(pCallBack pFunc);
I have written an interop dll:
````````````````````````````````````````
public class FooInterop
{
public delegate void pCallBack(int i);

[DllImport("Foo.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int
Foo([MarshalAs(UnmanagedType.FunctionPtr)]pCallBack pFunc);
}

And I'm trying to call it this way:
```````````````````````````````````````````````

class Class1
{
[STAThread]
static void Main(string[] args)
{
int res = FooInterop.Foo(new FooInterop.pCallBack(Class1.FooCB));
Console.WriteLine(res);
}

static public void FooCB(int i)
{
Console.WriteLine(i);
}
}

For some reason when leaving FooCB I get the following error:

"Run-Time Check Failure #0 - The value of ESP was not properly saved
across a function call. This is usually a result of calling a
function declared with one calling convention with a function pointer
declared with a different calling convention."

I'm assuming this is because 'Foo' (in the C dll) is defined as
__cdecl and 'FooCB' (in .NET assembly) is an __stdcall. Am I right?
How do I tell the marsheler that C# method should behave as __cdecl
in .NET 1.1?
How do I solve this problem?
BTW defining the typedef as stdcall (I.e. typedef void (__stdcall
*pCallBack)(int i); )
works OK, but I'm not surethis is the solution I need.
Any ideas?
Thanks!

Mar 20 '07 #2
"Udi" <Ud**********@gmail.comwrote in message
news:11**********************@e65g2000hsc.googlegr oups.com...
Hi All,

I have a C dll exporting the following:
`````````````````````````````````````````````````` ``
typedef void (__cdecl *pCallBack)(int i);

int __cdecl Foo(pCallBack pFunc);
I have written an interop dll:
````````````````````````````````````````
public class FooInterop
{
public delegate void pCallBack(int i);

[DllImport("Foo.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int
Foo([MarshalAs(UnmanagedType.FunctionPtr)]pCallBack pFunc);
}

And I'm trying to call it this way:
```````````````````````````````````````````````

class Class1
{
[STAThread]
static void Main(string[] args)
{
int res = FooInterop.Foo(new FooInterop.pCallBack(Class1.FooCB));
Console.WriteLine(res);
}

static public void FooCB(int i)
{
Console.WriteLine(i);
}
}

For some reason when leaving FooCB I get the following error:

"Run-Time Check Failure #0 - The value of ESP was not properly saved
across a function call. This is usually a result of calling a
function declared with one calling convention with a function pointer
declared with a different calling convention."

I'm assuming this is because 'Foo' (in the C dll) is defined as
__cdecl and 'FooCB' (in .NET assembly) is an __stdcall. Am I right?
How do I tell the marsheler that C# method should behave as __cdecl
in .NET 1.1?
How do I solve this problem?
BTW defining the typedef as stdcall (I.e. typedef void (__stdcall
*pCallBack)(int i); )
works OK, but I'm not surethis is the solution I need.
Callbacks should preferably be declared as __stdcall, this is the standard calling
convention for callbacks in windows and is the default in .NET.
So, Yes, this is the solution.
Willy.

Mar 20 '07 #3

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

Similar topics

3
by: ThinkRS232 | last post by:
I have a Win32 DLL that has a standard _stdcall (WINAPI) exports. I am able to call these fine from C#. One call in particular however has a callback to a CDECL function. How would I set that up?...
12
by: Tor Rustad | last post by:
Did a fun project some years ago.. a cdecl, but never really tested it. Here are some test cases I just tried: cdecl> char **argv; cdecl> argv is pointer to pointer to char Looks ok cdecl>...
3
by: Boots | last post by:
Hi all I am relatively new to C# programming and have run into a problem that I believe is caused by my C# function declarations. I believe that my C# function must use a CDecl CallingConvention...
2
by: KW | last post by:
I am converting a multithreaded MFC application to Managed C++ under VS2003 that uses a DLL that was compiled in Microsoft Visual Fortran 6. The main function of the fortran DLL (FVIS2FOR) takes a...
6
by: ReinhardH | last post by:
Hi, I have to use a cdecl dll (3 party dll). One of the functions needs a callback as a parameter. Unfortunately it seems that I'm not able to solve this issue. What I have done is: Declare...
5
by: richard.wm.jones | last post by:
I'm trying to track down the original authors of cdecl. cdecl was dropped from Fedora Core a few years ago because of licensing concerns. The original postings to comp.sources.unix (vols 6 & 14...
13
by: shanti | last post by:
hi, I know that this may not be the question has to be raised in this group. in comp.lang.c FAQ list · Question 1.21 i read about cdecl . i am working with "turbo c" on a windows xp mechine. can...
5
by: Jef Driesen | last post by:
I have a C DLL that I want to use from a C# project. The C header file contains these declarations: typedef void (*callback_t) (const unsigned char *data, unsigned int size, void *userdata);...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
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...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
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
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...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.