Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
UINT16 error
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  12 messages - Expand all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
James Crouch  
View profile  
 More options Sep 20 2005, 11:04 am
Newsgroups: microsoft.public.dotnet.languages.vc
From: "James Crouch" <james.cro...@wpafb.af.mil>
Date: Tue, 20 Sep 2005 11:04:33 -0400
Local: Tues, Sep 20 2005 11:04 am
Subject: UINT16 error
I am trying to create a managed c++ wrapper and have run into a problem is
when SetNewNetworkCallBack is run.  It doesn't like that NetworkID isn't an
UInt16.  I get the error:

CCommManager::SetNewNetworkCallBack' : cannot convert parameter 1 from 'void
(unsigned short,void *)' to 'void (__cdecl *)(UInt16,void *)'

Any help would be appreicated.  Offending code is below.

James

Managed Code:

CCommApp::CCommApp(char chan, long baud, String * ServerAddress, int
ListenPort, bool Logging)
{
    m_pComm->SetNewNetworkCallBack(NewNetwork, this);            //Problem
line

}

void CCommApp::NewNetwork(unsigned short NetworkID, void *Parameter)

Unmanaged Code Header:

void SetNewNetworkCallBack(void(*NewNetworkCallBack)(UInt16 NetworkID, void*
Parameter), void* Parameter);


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Doug Harrison [MVP]  
View profile  
 More options Sep 20 2005, 12:03 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: "Doug Harrison [MVP]" <d...@mvps.org>
Date: Tue, 20 Sep 2005 11:03:57 -0500
Local: Tues, Sep 20 2005 12:03 pm
Subject: Re: UINT16 error
On Tue, 20 Sep 2005 11:04:33 -0400, "James Crouch"

This has got nothing to do with managed vs unmanaged code or UINT16.
Apparently NewNetwork is a non-static member function, and VC7.1 is not
only allowing the illegal syntax for referring to it in your
SetNewNetworkCallBack call, it's emitting a misleading error message which
implies it's a static member. IIRC, VC8 fixes the syntax problem, so the
bare "NewNetwork" reference will be disallowed; instead, you'll have to use
&CCommApp::NewNetwork to form a pointer to member. In any case, the
solution is to make NewNetwork static.

P.S. It would be useful in the future to include the complete text of the
error message, including error number, and to abstract the problem into a
simple console program. For example (removing all the managed stuff doesn't
affect the error message):

#using <mscorlib.dll>
using namespace System;

#pragma unmanaged

void f(void (*)(unsigned short))
{

}

#pragma managed

struct X
{
   void g(unsigned short)
   {
   }

   void h()
   {
      f(g);
   }

};

int main()
{

}

C>ccr k.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 13.10.3077 for .NET
Framework
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

k.cpp
k.cpp(20) : error C2664: 'f' : cannot convert parameter 1 from 'void
(unsigned short)' to 'void (__cdecl *)(unsigned short)'
        None of the functions with this name in scope match the target type

--
Doug Harrison
VC++ MVP


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tamas Demjen  
View profile  
 More options Sep 20 2005, 12:13 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: Tamas Demjen <tdem...@yahoo.com>
Date: Tue, 20 Sep 2005 09:13:56 -0700
Local: Tues, Sep 20 2005 12:13 pm
Subject: Re: UINT16 error

Is CCommApp::NewNetwork static? The NewNetworkCallBack prototype
requires that the function is non-member or at least static. Just move
the NewNetwork function outside of the CComApp class, it doesn't belong
there.

Also check that UInt16 is exactly the same type as unsigned short
(better to rename Uint16 to unsigned short), and the calling conventions
must match too (both __stdcall or __cdecl, better to specify it explicitly).

Tom


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tamas Demjen  
View profile  
 More options Sep 20 2005, 12:21 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: Tamas Demjen <tdem...@yahoo.com>
Date: Tue, 20 Sep 2005 09:21:41 -0700
Local: Tues, Sep 20 2005 12:21 pm
Subject: Re: UINT16 error

James Crouch wrote:

If I see it correctly, you're passing a managed method as an unmanaged
pointer. That's not going to work. You have to write a global unmanaged
function (in MC++ or C++/CLI) that calls back to the managed code, and
pass this intermediate function to the unmanaged API. There's no way you
can pass a managed callback to an unmanaged library without this
intermediate layer.

Also, you can't pass a managed void* to the unmanaged part either, at
least not without pinning it.

Tom


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Crouch  
View profile  
 More options Sep 20 2005, 12:39 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: "James Crouch" <james.cro...@wpafb.af.mil>
Date: Tue, 20 Sep 2005 12:39:21 -0400
Local: Tues, Sep 20 2005 12:39 pm
Subject: Re: UINT16 error

Thanks for the info and advice.  But how do I go about creating that pointer
to member?  Thanks.

James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Crouch  
View profile  
 More options Sep 20 2005, 1:35 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: "James Crouch" <james.cro...@wpafb.af.mil>
Date: Tue, 20 Sep 2005 13:35:26 -0400
Local: Tues, Sep 20 2005 1:35 pm
Subject: Re: UINT16 error
I've pulled the NewNetwork method out and made it global which solved my
inital problem.  Now however, I an error while trying to pass "this" to
NewNetwork.  The "void *Parameter" is an echo of SetNewNetworkCallBack's
"this".  Do I need to do some pinning and if so how?

Thanks.

James

"Tamas Demjen" <tdem...@yahoo.com> wrote in message

news:OtCAl9fvFHA.3152@TK2MSFTNGP12.phx.gbl...


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tamas Demjen  
View profile  
 More options Sep 20 2005, 4:42 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: Tamas Demjen <tdem...@yahoo.com>
Date: Tue, 20 Sep 2005 13:42:45 -0700
Local: Tues, Sep 20 2005 4:42 pm
Subject: Re: UINT16 error

James Crouch wrote:
> I've pulled the NewNetwork method out and made it global which solved my
> inital problem.  Now however, I an error while trying to pass "this" to
> NewNetwork.  The "void *Parameter" is an echo of SetNewNetworkCallBack's
> "this".  Do I need to do some pinning and if so how?

> Thanks.

> James

You probably figured out that I replied without noticing James' post.

Well, I believe you're taking chances if you don't pin the "this". What
happens is that you pass the managed handle "this" to an unmanaged code,
which will in turn call back to the managed code passing back the
"this". The problem is that the .NET framework may move data around in
the memory in the meantime. I don't know how safe it is to pass a GC
handle to an unmanaged code, which passes the same handle back to
managed code. When you convert the GC handle into unmanaged void*, you
essentially store its internal representation (IntPtr). If the GC
decides to compact the heap, small objects may be moved around in the
memory, unless they are pinned. Now what happens if your "this" handle
is moved around while your unmanaged code is being executed? My rule of
thumb is to never get an IntPtr for a managed object without first
pinning it.

Can anybody confirm this?

Tom


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tamas Demjen  
View profile  
 More options Sep 20 2005, 6:03 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: Tamas Demjen <tdem...@yahoo.com>
Date: Tue, 20 Sep 2005 15:03:43 -0700
Local: Tues, Sep 20 2005 6:03 pm
Subject: Re: UINT16 error
I was curious how to do this, and worked out two very simple examples.
This is how I would implement a C-callback in managed C++ code. I
couldn't find anything that allowed a managed function to be passed
directly to an unmanaged call (first I couldn't convert between void*
and the managed type, second I couldn't convert between __clrcall and
__cdecl functions). So I had to introduced the intermediate class
"Bridge". gcroot<> is a wrapper for GCHandle, which allows us to store a
managed handle in a native class. It also ensures that the managed class
is pinned, so the garbage collector doesn't move around the "c" object
while the native code is running. After the native "Process" is done,
the bridge goes out of scope, so the pin gets released.

//////////////////////////////////////////////////////////////////
// For MC++:
#include "stdafx.h"
#include <vcclr.h>

#using <mscorlib.dll>

using namespace System;

typedef void (*Callback)(void* param);

void Process(Callback callback, void* param)
{
    if(callback) callback(param);

}

__gc class C
{
public:
    void ProcessMe();
    void OnProcess() // the callback implementation
    {
       Console::WriteLine(S"OnProcess");
    }

};

class Bridge
{
public:
    Bridge(C* in) : c(in) { }
    static void ForwardOnProcess(void* param)
    { static_cast<Bridge*>(param)->c->OnProcess(); }
private:
    gcroot<C*> c;

};

void C::ProcessMe()
{
    Bridge b(this);
    ::Process(&Bridge::ForwardOnProcess, &b);

}

int _tmain()
{
    C* c = new C;
    c->ProcessMe();
    return 0;

}

//////////////////////////////////////////////////////////////////
// For C++/CLI:
#include "stdafx.h"
#include <vcclr.h>

using namespace System;

typedef void (*Callback)(void* param);

void Process(Callback callback, void* param)
{
    if(callback) callback(param);

}

ref class C
{
public:
    void ProcessMe();
    void OnProcess() // the callback implementation
    {
       Console::WriteLine(L"OnProcess");
    }

};

class Bridge
{
public:
    Bridge(C^ in) : c(in) { }
    static void ForwardOnProcess(void* param)
    { static_cast<Bridge*>(param)->c->OnProcess(); }
private:
    gcroot<C^> c;

};

void C::ProcessMe()
{
    Bridge b(this);
    ::Process(&Bridge::ForwardOnProcess, &b);

}

int main(array<System::String^>^ args)
{
    C^ c = gcnew C;
    c->ProcessMe();
    return 0;

}

Tom

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Willy Denoyette [MVP]  
View profile  
 More options Sep 21 2005, 5:55 am
Newsgroups: microsoft.public.dotnet.languages.vc
From: "Willy Denoyette [MVP]" <willy.denoye...@telenet.be>
Date: Wed, 21 Sep 2005 11:55:02 +0200
Local: Wed, Sep 21 2005 5:55 am
Subject: Re: UINT16 error
IMO it's more flexible when using (typesafe) delegates...

#pragma unmanaged
class Unmanaged
{
   public:
   void Process( void (__stdcall *ptr) (int))
   {
   int i = 10;
   if(ptr != 0)
  ptr(i);
   }

};

// managed code from here
#pragma managed
public __gc class C
{
   public:
  static C* m_pClass = 0;
  __delegate void CbckProc(int v);
 private:
 // private inner non GC class used as thunk to callback into managed code
    __nogc class _C
    {
//     private:
     public:
     static void __stdcall CallbackProc(int v)
     {
     m_pClass->m_cbProc->Invoke(v); // Invoke delegate target
     }
  };

 public:
  C() { m_pClass = this; }
  ~C() { m_pClass = 0; }
  //Managed callback
  void OnProcess(int i)
   {
   System::Console::WriteLine(__box(i));
   }
  void ProcessMe()
  {
     m_cbProc = new CbckProc(this, &C::OnProcess);
     Unmanaged* n = new Unmanaged();
     n->Process(_C::CallbackProc);
  }
  CbckProc* m_cbProc;
  private:
    _C* m_c;

};

int main()
{
   C* c = new C();
   c->ProcessMe();

}

Willy.

"Tamas Demjen" <tdem...@yahoo.com> wrote in message

news:u4eir8ivFHA.2568@TK2MSFTNGP10.phx.gbl...


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tamas Demjen  
View profile  
 More options Sep 21 2005, 12:20 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: Tamas Demjen <tdem...@yahoo.com>
Date: Wed, 21 Sep 2005 09:20:00 -0700
Subject: Re: UINT16 error

Willy Denoyette [MVP] wrote:
> IMO it's more flexible when using (typesafe) delegates...

Good idea, thanks Willy.

>  // private inner non GC class used as thunk to callback into managed code
>     __nogc class _C

VC++ 2005 doesn't allow me to define an unmanaged class in a managed one:

ref class Managed
{
private:
    class Unmanaged
    {
    };

};

error C2814: 'Managed::Unmanaged' : a native type cannot be nested
within a managed type 'Managed'

Tom


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Willy Denoyette [MVP]  
View profile  
 More options Sep 21 2005, 12:35 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: "Willy Denoyette [MVP]" <willy.denoye...@telenet.be>
Date: Wed, 21 Sep 2005 18:35:28 +0200
Local: Wed, Sep 21 2005 12:35 pm
Subject: Re: UINT16 error

"Tamas Demjen" <tdem...@yahoo.com> wrote in message

news:eT2tRhsvFHA.916@TK2MSFTNGP10.phx.gbl...

Tom,

I know, and it's unfortunate C++/CLI does not support nested native types
(or mixed types), so you'll have to use the same "hack" as you did to make
it work but now using delegates. I guess there might be a cleaner way to
achieve the same.

#pragma unmanaged
class Unmanaged
{
   public:
   void Process(void (__stdcall *ptr) (void*, int), void* param)
   {
   int i = 10;
   if(ptr != 0)
      ptr( param, i);
   }

};

// managed code from here
#pragma managed

public ref class C
{
   public:
  delegate void CbckProc(int);

  //Managed static callback
  static void OnProcess(int v)
   {
   System::Console::WriteLine("Test {0}", v);
   }
    // Managed member callback
   void OnProcess2(int v)
   {
   System::Console::WriteLine("Test2 {0}", v);
   }

  void ProcessMe();
  CbckProc^ m_cbProc;

};

class Thunk
{
//     private:
  public:
  Thunk(C^ in):m_pClass(in){}
  static void __stdcall CallbackProc(void* param, int v)
  {
// here is the "ugly" cast back again
  static_cast<Thunk*>(param)->m_pClass->m_cbProc->Invoke(v);
  }
  gcroot<C^> m_pClass;
 };

void C::ProcessMe()
  {
  Thunk b(this);
  m_cbProc = gcnew CbckProc(&C::OnProcess);
  Unmanaged* n = new Unmanaged();
  n->Process(Thunk::CallbackProc, &b);
  m_cbProc = gcnew CbckProc(this, &C::OnProcess2);
  n->Process(Thunk::CallbackProc, &b);
  }

int main()
{
   C c;
   c.ProcessMe();


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Willy Denoyette [MVP]  
View profile  
 More options Sep 21 2005, 2:42 pm
Newsgroups: microsoft.public.dotnet.languages.vc
From: "Willy Denoyette [MVP]" <willy.denoye...@telenet.be>
Date: Wed, 21 Sep 2005 20:42:48 +0200
Local: Wed, Sep 21 2005 2:42 pm
Subject: Re: UINT16 error
Well I'm leaking the gcroot, to solve this I can use msclr::auto_gcroot<>
...

 #include <msclr\auto_gcroot.h>
..

  private:
      msclr::auto_gcroot<C^> m_pClass;
 };

or, I'll have to implement a destructor...

#include <msclr\gcroot.h>

    ~Thunk() {delete m_pClass;;}
..
    private:
      msclr::gcroot<C^> m_pClass;
    };

Willy.

"Willy Denoyette [MVP]" <willy.denoye...@telenet.be> wrote in message
news:%234GS9psvFHA.3124@TK2MSFTNGP12.phx.gbl...


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google