By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,310 Members | 1,430 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,310 IT Pros & Developers. It's quick & easy.

Callback Method Delegate as an Argument to Dll Functions

P: n/a
Hello,

I need some help getting a callback delegate passed as an argument to a
dynamically linked Dll method so it in turn, can eventually call it. Below
is the salient portions of code I'm dealing with. It all compiles and all
other dynamically linked methods that only pass "regular" arguments
(strings, ints, bools, objects, etc.) work great. However, when this
portion of code runs and hits the line that acutally invokes the Dll method,
it throws the following exception:

"Object type cannot be converted to target type."

Why am I not allowed to pass the callback delegate: cbMyCallBack to the Dll
method?
Why is it trying to convert the argument at all when the Dll callee method
and the argument type match?
Any help would be appreciated, TIA.
GloballyDelcared:

public delegate void NotifyCB();

Inside Object1:

public void SomeWorkerMethod()

{

....

Object2.DoWork(new NotifyCB(cbTheCallBack))

....

}

public static void cbTheCallBack()

{

//Do the callback here ...

}

Inside Object2:

private Assembly m_DllAssembly = Assembly.Load(DllName);

private Type m_oTypeEngine = =
m_DllAssembly.GetType("Namespace.ObjectName");

private object m_oActivator = Activator.CreateInstance(m_oTypeEngine);

private Type m_TypeInterface = =
m_oTypeEngine.GetInterface("InterfaceName");

private MethodInfo m_miMyDllMethod =
m_TypeInterface.GetMethod("MyDllMethod");;

....

public void DoWork(NotifyCB cbMyCallBack)

{

....

object[] oArgs = {cbMyCallBack};

bool bRtn = (bool)m_miMyDllMethod.Invoke(m_oActivator, oArgs);

....

}

Inside the Called DLL, Object3:

public void MyDllMethod(NotifyCB cbMyCallBack)

{

....

//Do some DLL work

....

cbMyCallBack();

}

--
John C. Bowman
Software Engineer
Thermo Electron Scientific Instruments Div.
<Remove this before reply> jo*********@thermo.com
Nov 15 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Please note: during the copying and pasting / sanitization process of the
code I included, I've introduced several typos that are not really part of
the code, such as = = where it should not be, multiple ;'s, etc. Please
ignore them.

TIA,

John

"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:Om**************@TK2MSFTNGP09.phx.gbl...
Hello,

I need some help getting a callback delegate passed as an argument to a
dynamically linked Dll method so it in turn, can eventually call it. Below
is the salient portions of code I'm dealing with. It all compiles and all
other dynamically linked methods that only pass "regular" arguments
(strings, ints, bools, objects, etc.) work great. However, when this
portion of code runs and hits the line that acutally invokes the Dll method, it throws the following exception:

"Object type cannot be converted to target type."

Why am I not allowed to pass the callback delegate: cbMyCallBack to the Dll method?
Why is it trying to convert the argument at all when the Dll callee method
and the argument type match?
Any help would be appreciated, TIA.
GloballyDelcared:

public delegate void NotifyCB();

Inside Object1:

public void SomeWorkerMethod()

{

...

Object2.DoWork(new NotifyCB(cbTheCallBack))

...

}

public static void cbTheCallBack()

{

//Do the callback here ...

}

Inside Object2:

private Assembly m_DllAssembly = Assembly.Load(DllName);

private Type m_oTypeEngine = =
m_DllAssembly.GetType("Namespace.ObjectName");

private object m_oActivator = Activator.CreateInstance(m_oTypeEngine);

private Type m_TypeInterface = =
m_oTypeEngine.GetInterface("InterfaceName");

private MethodInfo m_miMyDllMethod =
m_TypeInterface.GetMethod("MyDllMethod");;

...

public void DoWork(NotifyCB cbMyCallBack)

{

...

object[] oArgs = {cbMyCallBack};

bool bRtn = (bool)m_miMyDllMethod.Invoke(m_oActivator, oArgs);

...

}

Inside the Called DLL, Object3:

public void MyDllMethod(NotifyCB cbMyCallBack)

{

...

//Do some DLL work

...

cbMyCallBack();

}

--
John C. Bowman
Software Engineer
Thermo Electron Scientific Instruments Div.
<Remove this before reply> jo*********@thermo.com

Nov 15 '05 #2

P: n/a
Another Please note:

The Exception thrown is an ArgumentException with the message:

"Object type cannot be converted to target type."
TIA... again,

John
"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:Om**************@TK2MSFTNGP09.phx.gbl...
Hello,

I need some help getting a callback delegate passed as an argument to a
dynamically linked Dll method so it in turn, can eventually call it. Below
is the salient portions of code I'm dealing with. It all compiles and all
other dynamically linked methods that only pass "regular" arguments
(strings, ints, bools, objects, etc.) work great. However, when this
portion of code runs and hits the line that acutally invokes the Dll method, it throws the following exception:

"Object type cannot be converted to target type."

Why am I not allowed to pass the callback delegate: cbMyCallBack to the Dll method?
Why is it trying to convert the argument at all when the Dll callee method
and the argument type match?
Any help would be appreciated, TIA.
GloballyDelcared:

public delegate void NotifyCB();

Inside Object1:

public void SomeWorkerMethod()

{

...

Object2.DoWork(new NotifyCB(cbTheCallBack))

...

}

public static void cbTheCallBack()

{

//Do the callback here ...

}

Inside Object2:

private Assembly m_DllAssembly = Assembly.Load(DllName);

private Type m_oTypeEngine = =
m_DllAssembly.GetType("Namespace.ObjectName");

private object m_oActivator = Activator.CreateInstance(m_oTypeEngine);

private Type m_TypeInterface = =
m_oTypeEngine.GetInterface("InterfaceName");

private MethodInfo m_miMyDllMethod =
m_TypeInterface.GetMethod("MyDllMethod");;

...

public void DoWork(NotifyCB cbMyCallBack)

{

...

object[] oArgs = {cbMyCallBack};

bool bRtn = (bool)m_miMyDllMethod.Invoke(m_oActivator, oArgs);

...

}

Inside the Called DLL, Object3:

public void MyDllMethod(NotifyCB cbMyCallBack)

{

...

//Do some DLL work

...

cbMyCallBack();

}

--
John C. Bowman
Software Engineer
Thermo Electron Scientific Instruments Div.
<Remove this before reply> jo*********@thermo.com

Nov 15 '05 #3

P: n/a
What exactly do you mean by "GloballyDeclared"? I'm guessing that you've
got 2 projects each with their own copy of "public delegate void
NotifyCB();" which the runtime then treats as 2 distinct delegates types
that have no conversion. I believe the proper fix would be for one or the
other project to define NotifyCB, and then the other project needs to
reference it. Looking at your overall layout, I would guess the definition
of NotifyCB should exist in Object2's project.

--
--Grant
This posting is provided "AS IS" with no warranties, and confers no rights.
"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:uW**************@TK2MSFTNGP09.phx.gbl...
Another Please note:

The Exception thrown is an ArgumentException with the message:

"Object type cannot be converted to target type."
TIA... again,

John
"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:Om**************@TK2MSFTNGP09.phx.gbl...
Hello,

I need some help getting a callback delegate passed as an argument to a
dynamically linked Dll method so it in turn, can eventually call it. Below is the salient portions of code I'm dealing with. It all compiles and all other dynamically linked methods that only pass "regular" arguments
(strings, ints, bools, objects, etc.) work great. However, when this
portion of code runs and hits the line that acutally invokes the Dll

method,
it throws the following exception:

"Object type cannot be converted to target type."

Why am I not allowed to pass the callback delegate: cbMyCallBack to the

Dll
method?
Why is it trying to convert the argument at all when the Dll callee method and the argument type match?
Any help would be appreciated, TIA.
GloballyDelcared:

public delegate void NotifyCB();

Inside Object1:

public void SomeWorkerMethod()

{

...

Object2.DoWork(new NotifyCB(cbTheCallBack))

...

}

public static void cbTheCallBack()

{

//Do the callback here ...

}

Inside Object2:

private Assembly m_DllAssembly = Assembly.Load(DllName);

private Type m_oTypeEngine = =
m_DllAssembly.GetType("Namespace.ObjectName");

private object m_oActivator = Activator.CreateInstance(m_oTypeEngine);

private Type m_TypeInterface = =
m_oTypeEngine.GetInterface("InterfaceName");

private MethodInfo m_miMyDllMethod =
m_TypeInterface.GetMethod("MyDllMethod");;

...

public void DoWork(NotifyCB cbMyCallBack)

{

...

object[] oArgs = {cbMyCallBack};

bool bRtn = (bool)m_miMyDllMethod.Invoke(m_oActivator, oArgs);

...

}

Inside the Called DLL, Object3:

public void MyDllMethod(NotifyCB cbMyCallBack)

{

...

//Do some DLL work

...

cbMyCallBack();

}

--
John C. Bowman
Software Engineer
Thermo Electron Scientific Instruments Div.
<Remove this before reply> jo*********@thermo.com


Nov 15 '05 #4

P: n/a
Grant,

Thanks for the info. & response.What I meant by Globally Declared was that I
have a .CS file that defines it and that file is shared in both projects as
you surmised. But I did not realize the runtime would treat them as 2
distinct delegate types.

I'll take another look at it in the morning and try your idea and let you
know if it works.

Thanks!

John

"Grant Richins [MS]" <gr*****@online.microsoft.com> wrote in message
news:OF**************@TK2MSFTNGP12.phx.gbl...
What exactly do you mean by "GloballyDeclared"? I'm guessing that you've
got 2 projects each with their own copy of "public delegate void
NotifyCB();" which the runtime then treats as 2 distinct delegates types
that have no conversion. I believe the proper fix would be for one or the
other project to define NotifyCB, and then the other project needs to
reference it. Looking at your overall layout, I would guess the definition of NotifyCB should exist in Object2's project.

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

"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:uW**************@TK2MSFTNGP09.phx.gbl...
Another Please note:

The Exception thrown is an ArgumentException with the message:

"Object type cannot be converted to target type."
TIA... again,

John
"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:Om**************@TK2MSFTNGP09.phx.gbl...
Hello,

I need some help getting a callback delegate passed as an argument to a dynamically linked Dll method so it in turn, can eventually call it. Below is the salient portions of code I'm dealing with. It all compiles and all other dynamically linked methods that only pass "regular" arguments
(strings, ints, bools, objects, etc.) work great. However, when this
portion of code runs and hits the line that acutally invokes the Dll

method,
it throws the following exception:

"Object type cannot be converted to target type."

Why am I not allowed to pass the callback delegate: cbMyCallBack to
the Dll
method?
Why is it trying to convert the argument at all when the Dll callee

method and the argument type match?
Any help would be appreciated, TIA.
GloballyDelcared:

public delegate void NotifyCB();

Inside Object1:

public void SomeWorkerMethod()

{

...

Object2.DoWork(new NotifyCB(cbTheCallBack))

...

}

public static void cbTheCallBack()

{

//Do the callback here ...

}

Inside Object2:

private Assembly m_DllAssembly = Assembly.Load(DllName);

private Type m_oTypeEngine = =
m_DllAssembly.GetType("Namespace.ObjectName");

private object m_oActivator = Activator.CreateInstance(m_oTypeEngine);

private Type m_TypeInterface = =
m_oTypeEngine.GetInterface("InterfaceName");

private MethodInfo m_miMyDllMethod =
m_TypeInterface.GetMethod("MyDllMethod");;

...

public void DoWork(NotifyCB cbMyCallBack)

{

...

object[] oArgs = {cbMyCallBack};

bool bRtn = (bool)m_miMyDllMethod.Invoke(m_oActivator, oArgs);

...

}

Inside the Called DLL, Object3:

public void MyDllMethod(NotifyCB cbMyCallBack)

{

...

//Do some DLL work

...

cbMyCallBack();

}

--
John C. Bowman
Software Engineer
Thermo Electron Scientific Instruments Div.
<Remove this before reply> jo*********@thermo.com



Nov 15 '05 #5

P: n/a
Grant,

I tried your suggestion, but alas it still responds the same way. What
exactly did you mean by "and then the other project needs to reference it"?
If you mean I need to set a reference in the Dll to the cleint's project, I
can't do that because that's the EXE and you can't set references to EXE's.
If you mean I need to set a reference in the EXE project to the Dll, I can't
do that either because the Dll is unknown (except that it supports a
particular interface) until runtime and is totally on it's own and MUST use
late binding..

It would seem to me that passing a function pointer into a late bound Dll
method should be straightforward and common occurance. Is there some reason
one should be prevented from doing this? If so, I suppose I could try
triggering a special custom event. Unfortunately, my fear is that it won't
work either because the unknown Dll would have to support triggering the
special custom event. How can you enforce that when only methods are allowed
to be part of the interface?

Any more ideas/suggestions?

TIA,

John

"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:uq**************@TK2MSFTNGP09.phx.gbl...
Grant,

Thanks for the info. & response.What I meant by Globally Declared was that I have a .CS file that defines it and that file is shared in both projects as you surmised. But I did not realize the runtime would treat them as 2
distinct delegate types.

I'll take another look at it in the morning and try your idea and let you
know if it works.

Thanks!

John

"Grant Richins [MS]" <gr*****@online.microsoft.com> wrote in message
news:OF**************@TK2MSFTNGP12.phx.gbl...
What exactly do you mean by "GloballyDeclared"? I'm guessing that you've
got 2 projects each with their own copy of "public delegate void
NotifyCB();" which the runtime then treats as 2 distinct delegates types that have no conversion. I believe the proper fix would be for one or the other project to define NotifyCB, and then the other project needs to
reference it. Looking at your overall layout, I would guess the definition
of NotifyCB should exist in Object2's project.

--
--Grant
This posting is provided "AS IS" with no warranties, and confers no

rights.


"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in message news:uW**************@TK2MSFTNGP09.phx.gbl...
Another Please note:

The Exception thrown is an ArgumentException with the message:

"Object type cannot be converted to target type."
TIA... again,

John
"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in message news:Om**************@TK2MSFTNGP09.phx.gbl...
> Hello,
>
> I need some help getting a callback delegate passed as an argument
to
a > dynamically linked Dll method so it in turn, can eventually call it.

Below
> is the salient portions of code I'm dealing with. It all compiles
and
all
> other dynamically linked methods that only pass "regular" arguments
> (strings, ints, bools, objects, etc.) work great. However, when

this > portion of code runs and hits the line that acutally invokes the Dll
method,
> it throws the following exception:
>
> "Object type cannot be converted to target type."
>
> Why am I not allowed to pass the callback delegate: cbMyCallBack to

the Dll
> method?
> Why is it trying to convert the argument at all when the Dll callee

method
> and the argument type match?
>
>
> Any help would be appreciated, TIA.
>
>
> GloballyDelcared:
>
> public delegate void NotifyCB();
>
>
>
> Inside Object1:
>
> public void SomeWorkerMethod()
>
> {
>
> ...
>
> Object2.DoWork(new NotifyCB(cbTheCallBack))
>
> ...
>
> }
>
> public static void cbTheCallBack()
>
> {
>
> //Do the callback here ...
>
> }
>
>
>
>
>
> Inside Object2:
>
> private Assembly m_DllAssembly = Assembly.Load(DllName);
>
> private Type m_oTypeEngine = =
> m_DllAssembly.GetType("Namespace.ObjectName");
>
> private object m_oActivator = Activator.CreateInstance(m_oTypeEngine); >
> private Type m_TypeInterface = =
> m_oTypeEngine.GetInterface("InterfaceName");
>
> private MethodInfo m_miMyDllMethod =
> m_TypeInterface.GetMethod("MyDllMethod");;
>
> ...
>
> public void DoWork(NotifyCB cbMyCallBack)
>
> {
>
> ...
>
> object[] oArgs = {cbMyCallBack};
>
> bool bRtn = (bool)m_miMyDllMethod.Invoke(m_oActivator, oArgs);
>
> ...
>
> }
>
>
>
>
>
> Inside the Called DLL, Object3:
>
> public void MyDllMethod(NotifyCB cbMyCallBack)
>
> {
>
> ...
>
> //Do some DLL work
>
> ...
>
> cbMyCallBack();
>
> }
>
>
>
> --
> John C. Bowman
> Software Engineer
> Thermo Electron Scientific Instruments Div.
> <Remove this before reply> jo*********@thermo.com
>
>



Nov 15 '05 #6

P: n/a
<"John Bowman" <<Remove this before reply> jo*********@thermo.com>>
wrote:
I tried your suggestion, but alas it still responds the same way. What
exactly did you mean by "and then the other project needs to reference it"?
If you mean I need to set a reference in the Dll to the cleint's project, I
can't do that because that's the EXE and you can't set references to EXE's.


See http://www.pobox.com/~skeet/csharp/plugin.html

It's not dealing with delegates specifically, but it should give you an
idea of the options.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7

P: n/a
Jon,

Thanks for the link and insight, if gives me an idea to at leat try. What I
still don't understand is since I'm passing the delegate as an argument why
doesn't the Dll code recieve what's passed in and ues it at runtime, rather
than creating a separate delegate inside dll? I must be missing something...
(: .

John

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<"John Bowman" <<Remove this before reply> jo*********@thermo.com>>
wrote:
I tried your suggestion, but alas it still responds the same way. What
exactly did you mean by "and then the other project needs to reference it"? If you mean I need to set a reference in the Dll to the cleint's project, I can't do that because that's the EXE and you can't set references to
EXE's.
See http://www.pobox.com/~skeet/csharp/plugin.html

It's not dealing with delegates specifically, but it should give you an
idea of the options.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #8

P: n/a
Jon,

I tried it out and it works great. Thanks for the link/help!

John

"John Bowman jo*********@thermo.com>" <<Remove this before reply> wrote in
message news:%2****************@TK2MSFTNGP10.phx.gbl...
Jon,

Thanks for the link and insight, if gives me an idea to at leat try. What I still don't understand is since I'm passing the delegate as an argument why doesn't the Dll code recieve what's passed in and ues it at runtime, rather than creating a separate delegate inside dll? I must be missing something... (: .

John

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<"John Bowman" <<Remove this before reply> jo*********@thermo.com>>
wrote:
I tried your suggestion, but alas it still responds the same way. What
exactly did you mean by "and then the other project needs to reference it"? If you mean I need to set a reference in the Dll to the cleint's project, I can't do that because that's the EXE and you can't set references to

EXE's.

See http://www.pobox.com/~skeet/csharp/plugin.html

It's not dealing with delegates specifically, but it should give you an
idea of the options.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Nov 15 '05 #9

P: n/a
<"John Bowman" <<Remove this before reply> jo*********@thermo.com>>
wrote:
Thanks for the link and insight, if gives me an idea to at leat try. What I
still don't understand is since I'm passing the delegate as an argument why
doesn't the Dll code recieve what's passed in and ues it at runtime, rather
than creating a separate delegate inside dll? I must be missing something...
(: .


I don't believe it's creating a separate delegate - I believe it's not
able to reconcile what is passed to it as the type of delegate it is
expecting. Then again, I haven't looked at the code in detail.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #10

P: n/a
Jon,

Your description sounds like what I'm seeing, so I think you're right.

Thanks again,

John

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<"John Bowman" <<Remove this before reply> jo*********@thermo.com>>
wrote:
Thanks for the link and insight, if gives me an idea to at leat try. What I still don't understand is since I'm passing the delegate as an argument why doesn't the Dll code recieve what's passed in and ues it at runtime, rather than creating a separate delegate inside dll? I must be missing something... (: .


I don't believe it's creating a separate delegate - I believe it's not
able to reconcile what is passed to it as the type of delegate it is
expecting. Then again, I haven't looked at the code in detail.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.