我在IDL中声明了自己的结构,可是编译的时候硬是说名称没有声明……郁闷!我用的是VC.NET,错误信息如下:
d:\files\com\mp3tool\mp3file.h(32): error MIDL2025 : syntax error : expecting a type specification near "MP3_INFO_IDV1"
IDL代码如下:
// Mp3File.h : CMp3File 的声明#pragma once
#include "resource.h" // 主符号
#include <string>using namespace std;// Struct of Mp3 File infomation IDv1
typedef struct _MP3_INFO_IDV1
{
char Tag[3]; // IDv1标志,始终为“TAG”
char Title[30]; // 标题
char Artist[30]; // 艺术家
char Album[30]; // 专辑
char Year[4]; // 年代
char Comment[30]; // 注释
char Genre; // 风格
}MP3_INFO_IDV1;
// IMp3File
[
object,
uuid("2571A8A7-E284-4F88-A42C-A1AF74F8FDEE"),
dual, helpstring("IMp3File 接口"),
pointer_default(unique)
]__interface IMp3File : IDispatch
{
[id(1), helpstring("方法Open")] HRESULT Open([in] LPCTSTR lpszFilename);
[id(2), helpstring("方法Close")] HRESULT Close(void);
[id(3), helpstring("方法GetMp3Info")] HRESULT GetMp3Info([out] MP3_INFO_IDV1* info);
[id(4), helpstring("方法SetMp3Info")] HRESULT SetMp3Info([in] MP3_INFO_IDV1* info);
};// CMp3File[
coclass,
threading("apartment"),
vi_progid("Mp3Tool.Mp3File"),
progid("Mp3Tool.Mp3File.1"),
version(1.0),
uuid("329108FE-25AB-437E-A270-F78613E317DC"),
helpstring("Mp3File Class")
]
class ATL_NO_VTABLE CMp3File :
public IMp3File
{
public:
CMp3File()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}public: STDMETHOD(Open)(LPCTSTR lpszFilename);
STDMETHOD(Close)(void);
STDMETHOD(GetMp3Info)(MP3_INFO_IDV1* info);
STDMETHOD(SetMp3Info)(MP3_INFO_IDV1* info);
protected:
// // IDv1 Information
MP3_INFO_IDV1 m_Info1;
// // Full path name
string m_strFileName;
// // Opened Mp3 File handle
HANDLE m_hFile;
};
d:\files\com\mp3tool\mp3file.h(32): error MIDL2025 : syntax error : expecting a type specification near "MP3_INFO_IDV1"
IDL代码如下:
// Mp3File.h : CMp3File 的声明#pragma once
#include "resource.h" // 主符号
#include <string>using namespace std;// Struct of Mp3 File infomation IDv1
typedef struct _MP3_INFO_IDV1
{
char Tag[3]; // IDv1标志,始终为“TAG”
char Title[30]; // 标题
char Artist[30]; // 艺术家
char Album[30]; // 专辑
char Year[4]; // 年代
char Comment[30]; // 注释
char Genre; // 风格
}MP3_INFO_IDV1;
// IMp3File
[
object,
uuid("2571A8A7-E284-4F88-A42C-A1AF74F8FDEE"),
dual, helpstring("IMp3File 接口"),
pointer_default(unique)
]__interface IMp3File : IDispatch
{
[id(1), helpstring("方法Open")] HRESULT Open([in] LPCTSTR lpszFilename);
[id(2), helpstring("方法Close")] HRESULT Close(void);
[id(3), helpstring("方法GetMp3Info")] HRESULT GetMp3Info([out] MP3_INFO_IDV1* info);
[id(4), helpstring("方法SetMp3Info")] HRESULT SetMp3Info([in] MP3_INFO_IDV1* info);
};// CMp3File[
coclass,
threading("apartment"),
vi_progid("Mp3Tool.Mp3File"),
progid("Mp3Tool.Mp3File.1"),
version(1.0),
uuid("329108FE-25AB-437E-A270-F78613E317DC"),
helpstring("Mp3File Class")
]
class ATL_NO_VTABLE CMp3File :
public IMp3File
{
public:
CMp3File()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}public: STDMETHOD(Open)(LPCTSTR lpszFilename);
STDMETHOD(Close)(void);
STDMETHOD(GetMp3Info)(MP3_INFO_IDV1* info);
STDMETHOD(SetMp3Info)(MP3_INFO_IDV1* info);
protected:
// // IDv1 Information
MP3_INFO_IDV1 m_Info1;
// // Full path name
string m_strFileName;
// // Opened Mp3 File handle
HANDLE m_hFile;
};
解决方案 »
- .ocx注册成功,但是创建失败
- 用C++builder写的动态链接库可以给VC6中使用吗
- 获取TREE中鼠标所在坐标处的ITEM
- 求一个设计问题,关于数据返回的问题。
- CopyFile一旦失败,原来已存在的文件就要被删掉,那位高手不知有没有好一点的解决途径亚?
- CRecordSet里面修改值的问题
- 关于窗口重画问题
- windows9x下怎么看,一个应用程序加载的哪些dll
- 如果我通过注入DLL的方式注入了一个exe,如何判断这个exe运行的是个服务,还是普通exe
- 使用ATL/COM方式创建内嵌chart时出现 Access violation
- 50问一个基本问题:pBroadDocTemplate->OpenDocumentFile(NULL);在98下可以,但是在2000下的debug却出错,不知何故?
- 一个bug实在不知怎么回事,请大家帮个忙!
#include “mystruct.h”,但是编译不能通过。
后来改为“mystruct.idl”,编译能通过,但是不知道这样会不会有问题。btw:我用的是VC 6.0
简要说明:
(1) 从IUnknown继承的自定义接口 把数据结构直接传送给基于VTable接口的方法,只适用于由MIDL编译生成的proxy/stub DLL调度的接口,不能用于Invoke();(参UserDefinedDataType(1)) a.在一个新的.h文件中定义自定义数据结构. b.在.idl文件最前面加入这个.h文件,比如:#include "MyStruct.h" c.给从IUnknown派生的接口加入使用了自定义数据结构的方法。 d.在客户程序的stadafx.h最下面加入#import指令,如: #import "..\test3.tlb" no_namespace 在生成的.tlh文件中,会自动包含了用户自定义数据结构的定义。 e.在客户程序需要的时侯调用组件接口函数。 整个过程非常简单,与使用一般的自定义数据类型无异。 另外也可以很方便的使用自定义数据结构数组,使用方法如下: HRESULT Test2([in]int nCount, [in, size_is(nCount)]MyStruct *pStruct) (2)从IDispatch继承的双接口对于从IDispatch继承的双接口就不能象方法一那样直接在接口方法里申请自定义类型了,因为双接口必须要用与自动化兼容的类型。所以采用以下的步骤。 (参UserDefinedDataType(2)) a.首先在.idl文件中加入如下几句,定义一个自定义数据类型。 typedef [ uuid(44ABAE82-A173-11d4-98DB-0080C8F5B2E4)]
struct MyStruct
{
int x;
int y;
}MyStruct; b.接口方法参数定义为VARIANT类型,指针也一样。 c.客户端通过ClassWiard导入类型库(用#import也可以,不过这里要验证自动化) d.客户程序中要加入MyStruct的定义 e.客户程序中加入以下代码: const GUID GUID_MyStruct=
{0x44ABAE82,0xA173,0x11d4,{0x98,0xDB,0x00,0x80,0xC8,0xF5,0xB2,0xE4}};
const GUID LIBID_TEST6Lib =
{0x67061661,0xa2cb,0x11d4,{0x98,0xdb,0x00,0x80,0xc8,0xf5,0xb2,0xe4}}; ITypeLib* pTypeLib=NULL;
ITypeInfo* pTypeInfo=NULL;
IRecordInfo* pRecordInfo=NULL; LoadRegTypeLib(LIBID_TEST6Lib, 1, 0, LANG_NEUTRAL, &pTypeLib);
pTypeLib->GetTypeInfoOfGuid(GUID_MyStruct, &pTypeInfo);
GetRecordInfoFromTypeInfo(pTypeInfo, &pRecordInfo); MyStruct *pMyStruct = new MyStruct;
pMyStruct->x = pMyStruct->y = 100; VARIANT vr;
VariantInit(&vr);
vr.vt = VT_RECORD; //表明自定义类型
vr.pvRecord = (PVOID)pMyStruct; //指向实际数据
vr.pRecInfo = pRecordInfo; //包含了数据的一些信息
test6.Test2(vr); //调用接口方法 pTypeLib->Release();
pTypeInfo->Release();
pRecordInfo->Release();
f.在服务器组件接口方法的实现中加入以下几句: if (vr.vt == VT_RECORD)
{
IRecordInfo *pRecordInfo = vr.pRecInfo;
PVOID pMyStruct = vr.pvRecord;
VARIANT varX, varY;
int x=0, y=0; VariantInit(&varX);
VariantInit(&varY);
pRecordInfo->GetField(pMyStruct, L"x", &varX);//获得x字段的值
if (varX.vt == VT_INT)
{
x = varX.intVal;
}
pRecordInfo->GetField(pMyStruct, L"y", &varY);//获得y字段的值
if (varX.vt == VT_INT)
{
y = varY.intVal;
}
}
补: a.通过VARIANT,VT_RECORD,IRecordInfo的这种方法可以用自动化来传递自定义类型数据,但实际上这种方法只适用于双接口的情况。其原因在于实现组件IDispatch接口的IDispatchImpl类身上,它是通过VTable来调用方法的。如果是纯Dispatch接口就不能用这种方法,而我经过试验,暂时无法用这种方法实现dispinterface的情况。 b.同样的方法适用于安全数组,如果传递一个自定义数据结构的数组,则要用到SAFEARRAY,注意用类似SafeArrayCreateEx(VT_RECORD,1,&rgbounds,pRecInfo)的方法来创建数组。 (3)用dispinterface说明的纯IDispatch接口暂时没找到方法。
{
[id(1), helpstring("方法Open")] HRESULT Open([in] LPCTSTR lpszFilename);
[id(2), helpstring("方法Close")] HRESULT Close(void);
[id(3), helpstring("方法GetMp3Info")] HRESULT GetMp3Info([out] MP3_INFO_IDV1* info);
[id(4), helpstring("方法SetMp3Info")] HRESULT SetMp3Info([in] MP3_INFO_IDV1* info);
};在MP3_INFO_IDV1前面写上struct就可以了