无法将C#类转换为COM [英] Trouble converting C# class into COM

查看:64
本文介绍了无法将C#类转换为COM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我想将C#类转换为COM,以便我可以在C ++中使用该类。

代码编译和链接好。但是当我运行该程序时,我得到了一个

例外。

欢迎任何评论。在此先感谢。


Eric

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

在C#中编译成COM:


使用System;

使用System.Net;

使用System。 Net.Sockets;

使用System.Text;

使用System.Collections;


命名空间SonicBase

{

public delegate int dProc(byte [] buf,int offset,int size);

public class MyClass:IMyClass

{


私人dProc myProc = null;


bool StartServer(dProc dlgt)

{

myProc = dlgt;


byte [] buf = new byte [100];

int ret = myProc(buf,0,100);


返回(ret> 0);

}


bool SonicBase.IMyClass.StartServer(dProc dlgt )

{

返回false;

}


}

公共接口IMyClass

{

bool StartServe r(dProc dlgt);

}

}


-------------- -------------------------------------------------- ----------
$ C $ b在C ++中,使用COM:


//要使用C#服务器之类的托管代码服务器,

//我们必须导入公共语言运行时:

#import" mscorlib.tlb" raw_interfaces_only


#import" EricBase.tlb" no_namespace named_guids


extern" C"

int ProcData(char * buf,int offset,int size)

{

返回0;

}


void CMainFrame :: OnTest()

{

CoInitialize(NULL);


IMyClass * icp = NULL;

HRESULT hr = CoCreateInstance(CLSID_MyClass,

NULL,CLSCTX_INPROC_SERVER,

IID_IMyClass,reinterpret_cast< void **>(& icp));

DWORD count = 0;

AllocConsole();

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

WriteConsole(hOut,a \ n,2,& count,NULL);


if(FAILED(hr))

{

AfxMessageBox(" fail create");

返回;

}


尝试

{

_dProc * dlgt =(_ dProc * )ProcData;

icp-> StartServer(dlgt);

}

catch(_com_error e)

{

CString strInfo = e.ErrorMessage();

}


WriteConsole(hOut,b\ n,2,& count,NULL);


CoUninitialize();

}

解决方案

嗯......这很棘手。

你不能传递一个C函数ptr并直接用作委托指针,

你必须把它作为一个长整数(C / C ++)传递并将这个值编组为

FuctionPtr。

这是你应该做的。


1.改变你的C#代码..


公共接口IMyClass

{

bool StartServer(dProc dlgt);

}

进入:


公共接口IMyClass

{

bool StartServer([MarshalAs(UnmanagedType.FunctionPtr)] dProc dlgt); < br $>
}


2.您的C ++代码:


icp-> StartServer(dlgt);

进入:

// reinterpret_cast - 你知道你在做什么,不是吗?

icp-> StartServer(reinterpret_cas t< long>(dlgt));


为什么要为方法实现显式接口,没有必要

这样做只是声明你的接口方法为public。或者我错过了什么?b $ b Willy。

" Eric < WA ********** @ msn.com>在消息中写道

news:ub ************** @ TK2MSFTNGP15.phx.gbl ...

hi,

我想将C#类转换为COM,以便我可以在C ++中使用该类。
代码编译和链接很好。但是当我运行该程序时,我得到了一个
例外。
任何评论都是受欢迎的。提前致谢。

Eric

----------------------------- -----------------------------------------
在C#中编译成COM:

使用System;
使用System.Net;
使用System.Net.Sockets;
使用System.Text;
使用System。集合;

命名空间SonicBase
公共委托int dProc(byte [] buf,int offset,int size);
公共类MyClass:IMyClass
{

私人dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;
byte [] buf = new byte [100];
int ret = myProc(buf,0,100);

return(ret> 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
返回false;
}

}
>公共界面IMyClass
{
bool StartServer(dProc dlgt);
}
}

------------ -------------------------------------------------- ------------
在C ++中,使用COM:

//要使用C#服务器等托管代码服务器,我们必须导入公共语言运行库:
#import" mscorlib。 TLB" raw_interfaces_only

#import" EricBase.tlb" no_namespace named_guids
extern" C"
int ProcData(char * buf,int offset,int size)
{
返回0;
}

void CMainFrame :: OnTest()
{
CoInitialize(NULL);

IMyClass * icp = NULL;
HRESULT hr = CoCreateInstance (CLSID_MyClass,
NULL,CLSCTX_INPROC_SERVER,
IID_IMyClass,reinterpret_cast< void **>(& icp));

DWORD count = 0;
AllocConsole( );
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut,a \ n,2,& count,NULL);

if(FAILED) (hr))
{
AfxMessageBox(失败创建);
返回;
}

尝试
{
_dProc * dlgt =(_ dProc *)ProcData;
icp-> StartServer(dlgt);
}
catch(_com_error e)
{CS> strtring = e.ErrorMessage();
}

WriteConsole(hOut,b\ n,2,& count,NULL);

CoUninitialize( ); <无线电通信/>}



查看以下信息:
http://msdn.microsoft.com/library/de .. .nentstocom.asp


还要检查互操作新闻组:

microsoft.public.dotnet.framework.interop

" Eric" < WA ********** @ msn.com>在消息中写道

news:ub ************** @ TK2MSFTNGP15.phx.gbl ...

hi,

我想将C#类转换为COM,以便我可以在C ++中使用该类。
代码编译和链接很好。但是当我运行该程序时,我得到了一个
例外。
任何评论都是受欢迎的。提前致谢。

Eric

----------------------------- -----------------------------------------
在C#中编译成COM:

使用System;
使用System.Net;
使用System.Net.Sockets;
使用System.Text;
使用System。集合;

命名空间SonicBase
公共委托int dProc(byte [] buf,int offset,int size);
公共类MyClass:IMyClass
{

私人dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;
byte [] buf = new byte [100];
int ret = myProc(buf,0,100);

return(ret> 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
返回false;
}

}
>公共界面IMyClass
{
bool StartServer(dProc dlgt);
}
}

------------ -------------------------------------------------- ------ ------
在C ++中,使用COM:

//使用C#服务器等托管代码服务器,//我们必须导入公共语言运行时:
#import" mscorlib.tlb" raw_interfaces_only

#import" EricBase.tlb" no_namespace named_guids
extern" C"
int ProcData(char * buf,int offset,int size)
{
返回0;
}

void CMainFrame :: OnTest()
{
CoInitialize(NULL);

IMyClass * icp = NULL;
HRESULT hr = CoCreateInstance (CLSID_MyClass,
NULL,CLSCTX_INPROC_SERVER,
IID_IMyClass,reinterpret_cast< void **>(& icp));

DWORD count = 0;
AllocConsole( );
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut,a \ n,2,& count,NULL);

if(FAILED) (hr))
{
AfxMessageBox(失败创建);
返回;
}

尝试
{
_dProc * dlgt =(_ dProc *)ProcData;
icp-> StartServer(dlgt);
}
catch(_com_error e)
{CS> strtring = e.ErrorMessage();
}

WriteConsole(hOut," b\ n",2,& count,NULL);

CoUninitialize();
}





威利,


修改代码后,我又得到另一个例外,说无效

agument,我猜测委托dProc和
$ b之间会有一些不匹配$ b functionPtr ProcData,但我不知道出了什么问题。


我查看了MSDN,它只使用显式g /> $ b $获取样本b界面。你能不给我一个没有显式接口的样本?

使用接口将C#类导出到COM中很麻烦。这将是一个很好的乐趣,而不是在这里使用显式界面。


谢谢,

Eric

Willy Denoyette [MVP]" <无线************* @ pandora.be> D'è?óê?t

新闻:ux ************** @ TK2MSFTNGP14.phx.gbl ...

嗯......这很棘手。
你不能传递一个C函数ptr并直接用它作为委托指针,你必须把它作为一个长(C / C ++)和元帅传递这个值作为一个
FuctionPtr。
这是你应该做的。

1.改变你的C#代码..

公共接口IMyClass
{boor StartServer(dProc dlgt);
}
进入:公共接口IMyClass
{/ bool StartServer( [MarshalAs(UnmanagedType.FunctionPtr)] dProc dlgt);
}

2.您的C ++代码:

icp-> StartServer(dlgt);
进入:
// reinterpret_cast - 你知道你在做什么,不是吗?
icp-> StartServer(reinterpret_cast< long>(dlgt));

为什么要为该方法实现显式接口,没有
需要这样做只是将接口方法声明为public。或者我错过了什么?

威利。

" Eric" < WA ********** @ msn.com>在消息中写道
新闻:ub ************** @ TK2MSFTNGP15.phx.gbl ...

hi,
我想将C#类转换为COM,以便我可以在
C ++中使用该类。代码编译和链接很好。但是当我运行该程序时,我得到了一个
例外。
任何评论都是受欢迎的。提前致谢。

Eric

----------------------------- -----------------------------------------
在C#中编译成COM:

使用System;
使用System.Net;
使用System.Net.Sockets;
使用System.Text;
使用System。集合;

命名空间SonicBase
公共委托int dProc(byte [] buf,int offset,int size);
公共类MyClass:IMyClass
{

私人dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;
byte [] buf = new byte [100];
int ret = myProc(buf,0,100);

return(ret> 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
返回false;
}

}
>公共接口IMyClass
{
bool StartServer(dProc dlgt);
}
}



-------- -------------------------------------------------- ---------------- <在C ++中的blockquote class =post_quotes>,使用COM:

//要使用C#服务器之类的托管代码服务器,我们必须导入公共语言运行库:
#import" mscorlib.tlb" raw_interfaces_only

#import" EricBase.tlb" no_namespace named_guids
extern" C"
int ProcData(char * buf,int offset,int size)
{
返回0;
}

void CMainFrame :: OnTest()
{
CoInitialize(NULL);

IMyClass * icp = NULL;
HRESULT hr = CoCreateInstance (CLSID_MyClass,
NULL,CLSCTX_INPROC_SERVER,
IID_IMyClass,reinterpret_cast< void **>(& icp));

DWORD count = 0;
AllocConsole( );
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut,a \ n,2,& count,NULL);

if(FAILED) (hr))
{
AfxMessageBox(失败创建);
返回;
}

尝试
{
_dProc * dlgt =(_ dProc *)ProcData;
icp-> StartServer(dlgt);
}
catch(_com_error e)
{CS> strtring = e.ErrorMessage();
}

WriteConsole(hOut,b\ n,2,& count,NULL);

CoUninitialize( ); <无线电通信/>}




hi,

I want to convert a C# class into COM, so that I can use the class in C++.
The codes compile and link well. But when I run the program, I got a
exception.
Any comment is welcome. Thanks in advance.

Eric
----------------------------------------------------------------------
in C#, compile into a COM :

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;

namespace SonicBase
{
public delegate int dProc(byte[] buf, int offset, int size);
public class MyClass : IMyClass
{

private dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;

byte[] buf = new byte[100];
int ret = myProc(buf, 0, 100);

return (ret > 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
return false;
}

}

public interface IMyClass
{
bool StartServer(dProc dlgt);
}
}

--------------------------------------------------------------------------
in C++, use the COM :

// To use managed-code servers like the C# server,
// we have to import the common language runtime:
#import "mscorlib.tlb" raw_interfaces_only

#import "EricBase.tlb" no_namespace named_guids

extern "C"
int ProcData(char* buf, int offset, int size)
{
return 0;
}

void CMainFrame::OnTest()
{
CoInitialize(NULL);

IMyClass* icp = NULL;
HRESULT hr = CoCreateInstance(CLSID_MyClass,
NULL, CLSCTX_INPROC_SERVER,
IID_IMyClass, reinterpret_cast<void**>(&icp));
DWORD count=0;
AllocConsole();
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut, "a\n", 2, &count, NULL);

if(FAILED(hr))
{
AfxMessageBox("fail create");
return;
}

try
{
_dProc* dlgt = (_dProc*)ProcData;
icp->StartServer(dlgt);
}
catch(_com_error e)
{
CString strInfo = e.ErrorMessage();
}

WriteConsole(hOut, "b\n", 2, &count, NULL);

CoUninitialize();
}

解决方案

Hmm... this is tricky stuff.
You can''t pass a C function ptr and use it directly as a delegate pointer,
you have to pass it as a long (C/C++) and marshal this value as a
FuctionPtr.
Here''s what you should do.

1. change you C# code..

public interface IMyClass
{
bool StartServer(dProc dlgt);
}
into:

public interface IMyClass
{
bool StartServer([MarshalAs(UnmanagedType.FunctionPtr)]dProc dlgt);
}

2. Your C++ code:

icp->StartServer(dlgt);
into:
// reinterpret_cast - You know what you are doing, don''t you?
icp->StartServer(reinterpret_cast<long>(dlgt));

Why do you implement an explicit interface for the method, there is no need
to do this just declare your interface methods as public. Or am I missing
something?

Willy.
"Eric" <wa**********@msn.com> wrote in message
news:ub**************@TK2MSFTNGP15.phx.gbl...

hi,

I want to convert a C# class into COM, so that I can use the class in C++.
The codes compile and link well. But when I run the program, I got a
exception.
Any comment is welcome. Thanks in advance.

Eric
----------------------------------------------------------------------
in C#, compile into a COM :

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;

namespace SonicBase
{
public delegate int dProc(byte[] buf, int offset, int size);
public class MyClass : IMyClass
{

private dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;

byte[] buf = new byte[100];
int ret = myProc(buf, 0, 100);

return (ret > 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
return false;
}

}

public interface IMyClass
{
bool StartServer(dProc dlgt);
}
}

--------------------------------------------------------------------------
in C++, use the COM :

// To use managed-code servers like the C# server,
// we have to import the common language runtime:
#import "mscorlib.tlb" raw_interfaces_only

#import "EricBase.tlb" no_namespace named_guids

extern "C"
int ProcData(char* buf, int offset, int size)
{
return 0;
}

void CMainFrame::OnTest()
{
CoInitialize(NULL);

IMyClass* icp = NULL;
HRESULT hr = CoCreateInstance(CLSID_MyClass,
NULL, CLSCTX_INPROC_SERVER,
IID_IMyClass, reinterpret_cast<void**>(&icp));
DWORD count=0;
AllocConsole();
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut, "a\n", 2, &count, NULL);

if(FAILED(hr))
{
AfxMessageBox("fail create");
return;
}

try
{
_dProc* dlgt = (_dProc*)ProcData;
icp->StartServer(dlgt);
}
catch(_com_error e)
{
CString strInfo = e.ErrorMessage();
}

WriteConsole(hOut, "b\n", 2, &count, NULL);

CoUninitialize();
}



Check out the information at:
http://msdn.microsoft.com/library/de...nentstocom.asp

Also checkout the interop news group:
microsoft.public.dotnet.framework.interop
"Eric" <wa**********@msn.com> wrote in message
news:ub**************@TK2MSFTNGP15.phx.gbl...

hi,

I want to convert a C# class into COM, so that I can use the class in C++.
The codes compile and link well. But when I run the program, I got a
exception.
Any comment is welcome. Thanks in advance.

Eric
----------------------------------------------------------------------
in C#, compile into a COM :

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;

namespace SonicBase
{
public delegate int dProc(byte[] buf, int offset, int size);
public class MyClass : IMyClass
{

private dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;

byte[] buf = new byte[100];
int ret = myProc(buf, 0, 100);

return (ret > 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
return false;
}

}

public interface IMyClass
{
bool StartServer(dProc dlgt);
}
}

--------------------------------------------------------------------------
in C++, use the COM :

// To use managed-code servers like the C# server,
// we have to import the common language runtime:
#import "mscorlib.tlb" raw_interfaces_only

#import "EricBase.tlb" no_namespace named_guids

extern "C"
int ProcData(char* buf, int offset, int size)
{
return 0;
}

void CMainFrame::OnTest()
{
CoInitialize(NULL);

IMyClass* icp = NULL;
HRESULT hr = CoCreateInstance(CLSID_MyClass,
NULL, CLSCTX_INPROC_SERVER,
IID_IMyClass, reinterpret_cast<void**>(&icp));
DWORD count=0;
AllocConsole();
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut, "a\n", 2, &count, NULL);

if(FAILED(hr))
{
AfxMessageBox("fail create");
return;
}

try
{
_dProc* dlgt = (_dProc*)ProcData;
icp->StartServer(dlgt);
}
catch(_com_error e)
{
CString strInfo = e.ErrorMessage();
}

WriteConsole(hOut, "b\n", 2, &count, NULL);

CoUninitialize();
}




Hi, Willy,

After modifying the code, I got another exception saying that "invalid
agument", I guessed there would be some mismatch between delegate dProc and
functionPtr ProcData, but I don''t know what''s wrong.

I looked into the MSDN, it gaves only the samples using explicit
interface. Would you please give me a sample without an explicit interface?
Using interface to export a C# class into COM, is troublesome. It would be a
great pleasure not using the explicit interface here.

Thanks,
Eric
"Willy Denoyette [MVP]" <wi*************@pandora.be> D′è?óê?t
news:ux**************@TK2MSFTNGP14.phx.gbl...

Hmm... this is tricky stuff.
You can''t pass a C function ptr and use it directly as a delegate pointer,
you have to pass it as a long (C/C++) and marshal this value as a
FuctionPtr.
Here''s what you should do.

1. change you C# code..

public interface IMyClass
{
bool StartServer(dProc dlgt);
}
into:

public interface IMyClass
{
bool StartServer([MarshalAs(UnmanagedType.FunctionPtr)]dProc dlgt);
}

2. Your C++ code:

icp->StartServer(dlgt);
into:
// reinterpret_cast - You know what you are doing, don''t you?
icp->StartServer(reinterpret_cast<long>(dlgt));

Why do you implement an explicit interface for the method, there is no need to do this just declare your interface methods as public. Or am I missing
something?

Willy.
"Eric" <wa**********@msn.com> wrote in message
news:ub**************@TK2MSFTNGP15.phx.gbl...

hi,

I want to convert a C# class into COM, so that I can use the class in C++. The codes compile and link well. But when I run the program, I got a
exception.
Any comment is welcome. Thanks in advance.

Eric
----------------------------------------------------------------------
in C#, compile into a COM :

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;

namespace SonicBase
{
public delegate int dProc(byte[] buf, int offset, int size);
public class MyClass : IMyClass
{

private dProc myProc = null;

bool StartServer(dProc dlgt)
{
myProc = dlgt;

byte[] buf = new byte[100];
int ret = myProc(buf, 0, 100);

return (ret > 0);
}

bool SonicBase.IMyClass.StartServer(dProc dlgt)
{
return false;
}

}

public interface IMyClass
{
bool StartServer(dProc dlgt);
}
}



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

in C++, use the COM :

// To use managed-code servers like the C# server,
// we have to import the common language runtime:
#import "mscorlib.tlb" raw_interfaces_only

#import "EricBase.tlb" no_namespace named_guids

extern "C"
int ProcData(char* buf, int offset, int size)
{
return 0;
}

void CMainFrame::OnTest()
{
CoInitialize(NULL);

IMyClass* icp = NULL;
HRESULT hr = CoCreateInstance(CLSID_MyClass,
NULL, CLSCTX_INPROC_SERVER,
IID_IMyClass, reinterpret_cast<void**>(&icp));
DWORD count=0;
AllocConsole();
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut, "a\n", 2, &count, NULL);

if(FAILED(hr))
{
AfxMessageBox("fail create");
return;
}

try
{
_dProc* dlgt = (_dProc*)ProcData;
icp->StartServer(dlgt);
}
catch(_com_error e)
{
CString strInfo = e.ErrorMessage();
}

WriteConsole(hOut, "b\n", 2, &count, NULL);

CoUninitialize();
}




这篇关于无法将C#类转换为COM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆