打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Jan Kotas [MS] Callback function using C calling convention

The C# does not allow you to specify the calling convention of the callback.
It is just one of the C# limitations. IL, managed C++ and the runtime itself
supports the cdecl calling convention for delegates through
modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) on the
internal Invoke method of the delegate. Run ildasm on a small example in
managed C++ if you want to know the exact syntax.

You can use the following trick if you want to write all your code in C#:

- Create a private placeholder attribute to mark your C# delegates that
needs cdecl calling convention
- Compile your C# to an assembly
- Use the ildasm dissasembler to store the resulting assembly as raw IL.
- Modify the IL to change the calling convention on the delegates marked
with the placeholder attribute
- Use ilasm to compile the modified raw IL again.

The whole process can be automated. You can find example of how to automate
the process in the Shared Source CLI samples. The Shared Source CLI (aka
Rotor) can be downloaded from http://msdn.microsoft.com/net/sscli . The
following files have the interesting stuff about the cdecl calling
convention for delegates:

sscli\docs\techinfo\native_managed_interop.html
sscli\samples\pigui\tk\makefile.inc
sscli\samples\pigui\tk\callconvattribute.cs
sscli\samples\pigui\tk\callconvhack.pl
sscli\samples\pigui\tk\tclnative.cs

You will need perl (e.g. from http://www.activestate.com) if you want to use
the script as is. It should be fairly easy to rewrite callconvhack.pl in any
other language though.

Here are the code snipets if you are on a slow link and don‘t have time to
download 10+MB Rotor tarball at the moment:

makefile.inc:
--------------------
...
csc /out:myassembly.dll callconvattribute.cs mydelegate.cs ...
ildasm myassembly.dll /out:myassembly.il1
perl callconvhack.pl <myassembly.il1 >myassembly.il2
ilasm /DLL /QUIET myassembly.il2
...
--------------------

mydelegate.cs:
--------------------
...
[CallConvCdecl] internal delegate int MyDelegate(int param);
...
--------------------

callconvattribute.cs:
--------------------
// cdecl calling convetion for delegates - the signature of delegates
// marked with this attribute is changed to cdecl in callconvhack.pl

using System;

[Serializable, AttributeUsage (AttributeTargets.Delegate)]
public sealed class CallConvCdeclAttribute : Attribute
{
    public CallConvCdeclAttribute()
    {
    }

}

--------------------

callconvhack.pl:
--------------------
# change references to CallConvAttribute into
modopt([mscorlib]System.Runtime.CompilerServices.*)

while(<>) {
    if (m/\.class .* CallConv.*Attribute/) {
        $incallconvattributeimpl=1;
        next;
    }
    if(m/\/\/ end of class CallConv.*Attribute/) {
        $incallconvattributeimpl=0;
        next;
    }

    if(m/\.custom instance void CallConv(.*)Attribute/) {
        $pendingcallconv = $1;
        next;
    }

    if ($pendingcallconv) {
        if(m/.*Invoke\(.*/) {
            print
"modopt([mscorlib]System.Runtime.CompilerServices.CallConv" .
$pendingcallconv . ")\n";
            $pendingcallconv = "";
        }
    }

    print unless $incallconvattributeimpl;

}

--------------------

This posting is provided "AS IS" with no warranties, and confers no rights.

"Nicolas Faucher" <nicfauc...@hotmail.com> wrote in message

news:uwmLrrN6BHA.2360@tkmsftngp04...
> Hi,

> I hope you can help me on this.  I‘m calling a unmanaged C DLL from my C#
> application.  I‘m able to call the function correctly.  This function take
a
> pointer to a fonction (like callback functions in Win32).  I have declared
a
> delegate in my code and pass it to the unmanaged C function.  My callback
is
> called some times and after that I‘m receiving a NullReference exception.
I
> searched what‘s the problem and find that the callback function must use C
> calling convention.  I searched the documentation to find if there is a
way
> to specify the calling convention of a delegate (which I suppose is
stdcall
> by default) but without success.  I really think it‘s the cause of the
> exception thrown.

> So, how to change the calling convention of a delegate when used in
> unmanaged code?  If not, what I can do for this?  I know I can use Managed
> C++ to wrap this DLL but I really appreciate to have a totally C#
solution.

> Thanks

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
转 C++中的指针(二) 函数指针
x86 calling conventions
What's up with BeginInvoke? - starspace - 博客园
JNA API Documentation
在Flex中使用Delegate pattern来设计更好的对话框
结合自己接触的编程语言,写点最近接触C#与D之后的感想
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服