Click to See Complete Forum and Search --> : Passing __gc pointers to delegates


yoshiznit123
November 17th, 2005, 01:03 PM
Hi,
I'm using the DNSService library and one of the parameters for a delegate is a pointer to a managed class (DNSService::ServiceRef*). However, I get an error (C3160 'm_impl': cannot declare interior __gc pointer as member of DNSService::ServiceRef) when I try to compile this:


__gc struct PeerReply
{
static void OnBrowseReply(DNSService::ServiceRef* sdRef, ...more params) <---Error C3160
{
...stuff
}
};

int Initialize()
{
DNSService::Browse(0, 0, "_daap._tcp", NULL, new DNSService::BrowseReply(0, &PeerReply::OnBrowseReply));
}


I just got this code by converting a C# sample to managed C++, and it worked fine in C#... Could anybody please help? Thanks!

darwen
November 17th, 2005, 04:57 PM
Managed structs should be declared with __value and not __gc as they are value types, not garbage collected types.

You should make your struct a class.

Also you don't need the & infront of the method name in C++.

Darwen.

yoshiznit123
November 17th, 2005, 06:11 PM
Thanks for the suggestions... I changed it to a __gc class, but I still get the same error:

error C3160: 'm_impl' : cannot declare interior __gc pointer or reference as a member of 'DNSService::ServiceRef'

...even though I don't even have a variable called m_impl. Is it possible that there's a bug in the library? (Wouldn't think so tho, cuz it's Apple's Rendezvous lib)... thanks again

cilu
November 18th, 2005, 04:39 AM
You didn't show us the code that matters to understant where the problem is. I suggest you post the content of PeerReply class.

BTW, I would not think of a bug in the library.

yoshiznit123
November 18th, 2005, 10:32 AM
#using <dnssd.net.dll>

__gc class PeerReply
{
public:
static void OnBrowseReply(DNSService::ServiceRef* sdRef, DNSService::ServiceFlags flags, int interfaceIndex, DNSService::ErrorCode errorCode, String* name, String* type, String* domain) <---ERROR
{
Console::WriteLine("hey");
}
};

int Initialize()
{
DNSService::Browse(0, 0, "_daap._tcp", NULL, new DNSService::BrowseReply(0, PeerReply::OnBrowseReply));

return 0;
}


Initialize is called from an external program (this is a DLL). The problem is error C3160: 'm_impl' : cannot declare interior __gc pointer or reference as a member of 'DNSService::ServiceRef' on the marked line... It's weird because I don't have m_impl anywhere in my code... Thanks again. (its pissing me off because its the only error :-))

NoHero
November 18th, 2005, 10:40 AM
C3160 (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcerrCompilerErrorC3160.asp)


Maybe its the fault of the dnssd.net.dll class?

yoshiznit123
November 18th, 2005, 12:03 PM
that's the thing though, I got it from Apple (actually Aspecto software), and the sample compiles fine. and I pretty much just copied straight from their source... maybe its an error in the project settings? thanks for the help

oh and I probably should have mentioned this before, but when I import dnssd.net.dll it also gives a bunch of warnings saying that stuff is already declared:


#using <mscorlib.dll>
#using <System.dll>
#using <dnssd.net.dll>


gives
warning C4944: 'HINSTANCE__' : cannot import symbol from 'e:\projects\TuneShare\dnssd.net.dll': as 'HINSTANCE__' already exists in the current scope
along with 'hostent', 'in_addr' and some more (7 total)

NoHero
November 18th, 2005, 12:14 PM
You should post the source code that causes the include errors. This will help us to detect the source for all evil...

yoshiznit123
November 18th, 2005, 12:44 PM
alright, here goes... this is the code for a DLL that is a plugin for Winamp


#using <mscorlib.dll>
#using <System.dll>

#include "gen_ml/listview.h"
#include "gen_ml/itemlist.h"
#include "gen_ml/childwnd.h"
#include "gen_ml/ml.h"
#include "winamp/wa_ipc.h"
#include "winamp/wa_dlg.h"
#include "winamp/ipc_pe.h"
#include "resource.h"

#using <dnssd.net.dll>

#define VERSION "1.0"
#define CONFIG "ml_share"

using namespace System;

extern winampMediaLibraryPlugin plugin;

char *conf_file;
static HWND hWnd;
static int root_param;
static W_ListView list_view;
static int skin_handle;

__gc class PeerReply
{
public:
static void OnBrowseReply(DNSService::ServiceRef* sdRef, DNSService::ServiceFlags flags, int interfaceIndex, DNSService::ErrorCode errorCode, String* name, String* type, String* domain)
{
Console::WriteLine("hey");
}
};

int Initialize()
{
conf_file = (char*)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETINIFILE);

mlAddTreeItemStruct ml_root = {0, "Shared Music", 1,};
SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&ml_root, ML_IPC_ADDTREEITEM);
root_param = ml_root.this_id;

DNSService::Browse(0, 0, "_daap._tcp", NULL, new DNSService::BrowseReply(0, PeerReply::OnBrowseReply));

return 0;
}

void Quit()
{
return;
}

int MessageHandler(int type, int param1, int param2, int param3)
{
...just a message handler
}

extern winampMediaLibraryPlugin plugin = {MLHDR_VER, "TuneShare v" VERSION, Initialize, Quit, MessageHandler,};

extern "C" {__declspec(dllexport) winampMediaLibraryPlugin* winampGetMediaLibraryPlugin(){return &plugin;}};


basically winamp just calls init when it loads this DLL. This mixes a lot of managed and unmanaged code though, that might be part of the problem...
thanks a lot for the quick replies too :-)