C++에서 COM 개체를 사용하는 방법에 대한 자세한 자습서를 여러 번 따라 왔습니다. VS 2010 프로를 사용하고 있습니다. 나는 TestComInterop
이라는 새로운 솔루션을 만들었습니다. TestMath
이라는 C# 프로젝트를 만들었습니다. properties->Assembly Information->Make assembly COM-visible
에서 옵션을 선택하면 광고가 보이게됩니다. 나는 그 다음 Signing 속성으로 가서 MyMathCom.snk
(비밀 번호 없음)이라 불리는 총회에 서명했다. 그런 다음 GUID generator
을 사용하고 2 개의 GUID를 만들었습니다. 그런 다음이 코드를 내 프로그램에 넣고 컴파일하십시오. (성공)C++에서 관리되는 COM 개체 사용
using System.Runtime.InteropServices;
namespace TestMath
{
[Guid("599AD473-B0A9-4A6E-B260-CF6FDEBF151B"),InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IClass1
{
void AddNumbers(byte[] array);
}
[Guid("62FBC3A9-E2C0-4B53-9BF3-FDE22AA0CFF2"),ClassInterface(ClassInterfaceType.None)]
public class Class1 : IClass1
{
public void AddNumbers(byte[] array)
{
ulong number = 0;
foreach (var item in array)
{
number += item;
}
System.Console.WriteLine("The answer is {0}", number);
System.Windows.Forms.MessageBox.Show("DOrk");
}
}
}
다음으로 콘솔 응용 프로그램 용 C++ 프로젝트를 만들었습니다. 허용 된 MFC.
그런 다음 Typelib
MFC 클래스를 추가했습니다. 드롭 다운 상자를 사용하여 TestMath<1.0>
을 찾을 수 있었고 내 iClass1
이있었습니다. 나는 그 선택 그리고 그것은 나를
// Machine generated IDispatch wrapper class(es) created with Add Class from Typelib Wizard
#import "C:\\Users\\rsny\\Desktop\\TestComInterop\\TestComInterop\\TestMath\\bin\\Debug\\TestMath.tlb" no_namespace
// CClass1 wrapper class
class CClass1 : public COleDispatchDriver
{
public:
CClass1(){} // Calls COleDispatchDriver default constructor
CClass1(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
CClass1(const CClass1& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}
// Attributes
public:
// Operations
public:
// IClass1 methods
public:
void AddNumbers(SAFEARRAY * array)
{
static BYTE parms[] = {VTS_NONE} ;
InvokeHelper(0x60020000, DISPATCH_METHOD, VT_EMPTY, NULL, parms, array);
}
// IClass1 properties
public:
};
컴파일을위한 헤더 파일을 만들어, 그것은 .. 나를 위해 성공을 tlh
및 tli
파일을 만든 ..
그래서 다음 마지막 단계 내 코드를 실행하는 것입니다. TestComInterop.cpp
을 열었습니다.이 작업을 수행하는 "표준"방법을 찾을 수 없었습니다. 나는 여러 가지 다른 일을 시도했지만 넣어하는 것이 무엇인지 확실하지 않았다 봤는데 ... 여기 내 내 콘솔에 대한 답을 붙여 그것을 기대하고있어 이제
// TestComInterop.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "TestComInterop.h"
#include "CClass1.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only application object
CWinApp theApp;
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
}
}
else
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}
CClass1* myMath = new CClass1;
myMath->CreateDispatch("62FBC3A9-E2C0-4B53-9BF3-FDE22AA0CFF2");
//bool result = myMath.
if (myMath)
cout << "AWESOME" << endl;
else
cout << "LAME" << endl;
unsigned char numbers[5] = {0x01,0x02,0x03,0x04,0x05};
myMath->AddNumbers((SAFEARRAY*)numbers);
delete myMath;
getchar();
return nRetCode;
}
에 대한 코드 .. 불과하다 . 나는 또한 그것이 메시지 박스를 표시하기를 기대하고있다 ... 아무 것도. 말로하면, 적어도 COM 객체에 대해서는 newb입니다. 지금까지이 도구를 만드는 것은 모든 도구로 너무 어려워하지 않았습니다 ... 그러나 나에게있어서 나는 이것을 작동시킬 수 없습니다.
여기 내 tlh
및 tli
파일이 필요합니다. 당신이 COleDispatchDriver
파생 클래스를 사용하는 이유
// Created by Microsoft (R) C/C++ Compiler Version 10.00.30319.01 (e323d9ba).
//
// c:\users\rsny\desktop\testcominterop\testcominterop\testcominterop\debug\testmath.tli
//
// Wrapper implementations for Win32 type library C:\\Users\\rsny\\Desktop\\TestComInterop\\TestComInterop\\TestMath\\bin\\Debug\\TestMath.tlb
// compiler-generated file created 09/14/12 at 12:08:08 - DO NOT EDIT!
#pragma once
//
// interface IClass1 wrapper method implementations
//
inline HRESULT IClass1::AddNumbers (SAFEARRAY * array) {
HRESULT _hr = raw_AddNumbers(array);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _hr;
}
// Created by Microsoft (R) C/C++ Compiler Version 10.00.30319.01 (e323d9ba).
//
// c:\users\rsny\desktop\testcominterop\testcominterop\testcominterop\debug\testmath.tlh
//
// C++ source equivalent of Win32 type library C:\\Users\\rsny\\Desktop\\TestComInterop\\TestComInterop\\TestMath\\bin\\Debug\\TestMath.tlb
// compiler-generated file created 09/14/12 at 12:08:08 - DO NOT EDIT!
#pragma once
#pragma pack(push, 8)
#include <comdef.h>
//
// Forward references and typedefs
//
struct __declspec(uuid("d29ff1b5-bf10-4bbe-9bd9-cb5346f4bfaf"))
/* LIBID */ __TestMath;
struct __declspec(uuid("599ad473-b0a9-4a6e-b260-cf6fdebf151b"))
/* dual interface */ IClass1;
struct /* coclass */ Class1;
//
// Smart pointer typedef declarations
//
_COM_SMARTPTR_TYPEDEF(IClass1, __uuidof(IClass1));
//
// Type library items
//
struct __declspec(uuid("599ad473-b0a9-4a6e-b260-cf6fdebf151b"))
IClass1 : IDispatch
{
//
// Wrapper methods for error-handling
//
HRESULT AddNumbers (
SAFEARRAY * array);
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall raw_AddNumbers (
/*[in]*/ SAFEARRAY * array) = 0;
};
struct __declspec(uuid("62fbc3a9-e2c0-4b53-9bf3-fde22aa0cff2"))
Class1;
// interface _Object
// [ default ] interface IClass1
//
// Wrapper method implementations
//
#include "c:\users\rsny\desktop\testcominterop\testcominterop\testcominterop\debug\testmath.tli"
#pragma pack(pop)
코드가 잘 컴파일되었습니다. :)하지만 슬픈 메모는 그걸로 액세스 위반 오류가 발생했습니다. CoInitialize가 호출되지 않았다고합니다. 그래서 나는 그 오류를 찾아서 그것에 대해 무엇을보고 잠시 후에 다시 점검 할 것입니다. 팁 주셔서 감사합니다. SAFEARRAY 비트에 대한 단서가 없었습니다. 마지막으로 COleDispatchDriver를 만들지 않았습니다. 클래스 마법사를 사용하고 typelib에서 새 클래스를 추가했을 때 저를 위해 만들어졌습니다. –
COM 메서드를 호출하기 전에 COM을 초기화해야합니다. 응용 프로그램의 시작 부분 (예 :'_tmain'의 시작 부분)에서'CoInitialize (NULL) '을 호출하십시오. –