是否可以从Java调用COM API(特别是HP/Mercury Quality Center OTA API)?如果是这样,最好的方法是什么?
像JACOB这样适合吗?
代码片段对基础知识有帮助:-)
COM接口方法可以返回各种HRESULT值来表示传递的无效参数值.我什么E_POINTER时候回来E_INVALIDARG?
据我所知,如果一个方法在封装集合中接收索引并且它超出了界限E_INVALIDARG.如果一个方法接收到一个Interface**指针,它指的是存储一个指向新创建的对象的指针E_POINTER.
HRESULT CImpl::GetItem( long index; Interface** result )
{
if( result == 0 ) {
return E_POINTER;
}
if( index < 0 || index >= internalArray.size() ) {
return E_INVALIDARG;
}
*result = CreateWrapperObject( internalArray[index] );
return S_OK;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果它收到一个WCHAR*文件名为"in"参数的缓冲区并且这WCHAR*是空的呢?是这个E_POINTER还是E_INVALIDARG?
或者一个方法接收一个指向某个结构的指针,并期望通过该指针填充结构,并且该指针为空 - 是这个E_POINTER还是E_INVALIDARG?
HRESULT CImpl::SaveToFile( WCHAR* fileName )
{
if( fileName == 0 ) { …Run Code Online (Sandbox Code Playgroud) 我正在使用ESRI的ArcObjects COM库,我正在努力弄清楚"选择"应该是什么类型:
IMxDocument doc = m_application.Document as IMxDocument;
object selected = doc.SelectedItem;
Run Code Online (Sandbox Code Playgroud)
SelectedItem返回一个comobject(Not Null),通常表示当前选择的数据类型.但是我没有最微弱的想法,我应该把它投入到什么类型.当我调试它时,我真的没有看到任何有用的东西:
(在设置值后观察调试)
ESRI的ArcObjects库非常庞大,文档记录很差,我简直无法理解.我甚至竟然手动检查了大约50个我认为应该是的界面.
有没有人有任何想法我怎么能搞清楚这一点?
编辑澄清他们的文档绝对没有帮助,他们的论坛也没有.
我需要从我的.Net4应用程序自动化办公文档(Word和Excel).
由于我无法真正强迫我的用户使用特定的Office版本,因此我不使用互操作程序集或tlbimp,因此我的项目不包含任何其他引用,如果未安装Office,整个应用程序也将失败(功能刚赢了)不可用).
相反,我问系统哪个COM服务器可以处理"Word.Application"或"Excel.Application":
dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"));
app.Foo();
Run Code Online (Sandbox Code Playgroud)
我担心如何在完成后正确处理"app"对象,因为现在我有两个内部管理系统需要担心(COM引用计数和.Net引用跟踪).理想情况下,我应该能够将动态app对象包装到一次性包装器类中,并确保在处理包装器时底层COM对象未被引用.
编辑:此外,我想知道当我完成它时如何正确地使COM对象"活着",因为Word是在一个单独的过程中.我应该能够实例化Word应用程序,自动化它,然后释放我的所有引用,但Word应用程序应该保持打开状态.
我开发了一个C++类来访问USB上的软件保护加密狗.C++类是用Linux下的g ++开发的,但我可以在Windows下使用MinGW成功编译它.我有一个用VB6(Visual Basic 6)构建的科学应用程序.
问题是如何将我的C++类暴露给VB6应用程序?有什么可能的方法呢?我需要使用COM吗?(好吧,"微软少"的解决方案更可取:)
非常感谢您的帮助!
更新1.阅读您的注释我意识到我需要为C++类实现一个COM包装器.周围有什么好的和最近的例子吗?我可以使用MinGW(并避免MSVC)实现COM包装器吗?
更新2.最后,我决定为这个问题提供赏金.以下是我想要更好理解的内容:
1.我意识到我需要为我的C++类实现一个COM包装器.有人可以请我提供一个工作示例,说明如何为这样的课程:
class ValueMapper
{
public:
ValueMapper( ) { }
ValueMapper( double fmin, double fmax, int ilength ) {
SetMapping( fmin, fmax, ilength );
}
inline double GetMin() { return min; }
inline double GetMax() { return max; }
inline int GetLength() { return length; }
virtual inline void SetMapping( double fmin, double fmax, int ilength )
{
min = fmin;
max = fmax;
length = ilength;
}
virtual inline …Run Code Online (Sandbox Code Playgroud) 我有一个C#WPF(.NET 4.0)应用程序,它使用Excel互操作从Excel文件中读取数据.
当我在具有Excel 2007的开发机器上运行此应用程序时,它工作正常.当我在另一台安装了Excel 2010的计算机上运行它时,它失败并显示以下错误消息:
System.Runtime.InteropServices.COMException(0x80040154):由于以下错误,检索CLSID为{00024500-0000-0000-C000-000000000046}的组件的COM类工厂失败:80040154未注册类(HRESULT异常:0x80040154(REGDB_E_CLASSNOTREG) )).
尝试创建Microsoft.Office.Interop.Excel.Application对象时发生故障,如:
var app = new Application();
Run Code Online (Sandbox Code Playgroud)
我的项目引用了Microsoft.Office.Interop.Excel.dll(版本14.0.0.0,运行时版本v2.0.50727),它位于:
用于Office\PIA\Office14\Microsoft.Office.Interop.Excel.dll的C:\ Program Files\Microsoft Visual Studio 10.0\Visual Studio工具
我尝试使用引用的dll上的默认设置运行应用程序:
我还尝试在引用的dll上使用以下设置运行应用程序:
但是在使用Office 2010的计算机上,这些尝试都没有奏效.
其他说明:Office 2010的计算机是64位w/Windows 7.我的开发计算机是带有Windows XP的X86.
题
是什么导致"类未注册"异常,我该如何解决?
编辑
为了回应Alex的回答,我尝试将应用程序构建为任何CPU,X86和X64,但它没有任何区别.我仍然得到相同的"类未注册"错误.
编辑2
刚刚使用Office 2010在32位计算机上试用过该应用程序.没有错误.因此,特定机器可能出现问题,或者可能是64位和Office 2010的组合.
编辑3
好的,现在我已经在Office 2010的另一台64位计算机上测试了它.再次没有错误.我认为这意味着特定机器出了问题,这不是我软件的错.啊编程.
我想检索DirectX 9的错误字符串,但我可以在网上找到使用FormatMessage()和_com_error.ErrorMessage(),这两个都让我失望.
hr = g_pd3dDevice->GetRenderTargetData(...
... // the debugger tells me hr = 0x8876086c
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, hr, 0, (LPTSTR)&lpBuf, 0, NULL))
// it returns 0 with lpBuf unallocated
Run Code Online (Sandbox Code Playgroud)
FormatMessage()失败,我再次使用GetLastError()来查看FormatMessage()失败的原因:"系统无法在%2的消息文件中找到消息号0x%1的消息文本."
_com_error.ErrorMessage()告诉我"未知错误0x8876086c"
我有一个免注册的C++ COM组件,其清单我使用VS2010生成mt.exe.一切正常,除了我无法指定我的类使用哪个线程模型.我创建了一个小的repro项目,其生成的清单文件(RGS.dll.embed.manifest)如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="RGS.dll" hashalg="SHA1">
<comClass clsid="{4EB506E0-0D9C-4281-9B61-F027376E21C3}" tlbid="{6B48D06F-A84C-4B72-A70F-F1B091789E67}"></comClass>
<typelib tlbid="{6B48D06F-A84C-4B72-A70F-F1B091789E67}" version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib>
</file>
<comInterfaceExternalProxyStub name="IRgsObject1" iid="{4620CAB8-3E56-42EC-818E-8A55DF9267B7}" tlbid="{6B48D06F-A84C-4B72-A70F-F1B091789E67}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub>
</assembly>
Run Code Online (Sandbox Code Playgroud)
我遇到问题的部分是comClass节点
<comClass clsid="{4EB506E0-0D9C-4281-9B61-F027376E21C3}"
tlbid="{6B48D06F-A84C-4B72-A70F-F1B091789E67}"></comClass>
Run Code Online (Sandbox Code Playgroud)
应具有threadingModel属性,如下页"Sxs和注册免费COM激活"示例所示:http: //blogs.msdn.com/b/junfeng/archive/2006/04/20/579748.aspx
我知道线程模型没有在中指定*.tlb,但是从Sen Harada对MSDN文档的评论中mt.exe,您应该能够在注册脚本文件中指定一个(*.rgs)
http://msdn.microsoft.com/en-us /library/windows/desktop/aa375649(v=vs.85).aspx
所以我有*.rgsATL向导创建的文件
HKCR
{
NoRemove CLSID
{
ForceRemove {4EB506E0-0D9C-4281-9B61-F027376E21C3} = s 'RgsObject1 Class'
{
ForceRemove Programmable
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Neutral'
}
TypeLib = s '{6B48D06F-A84C-4B72-A70F-F1B091789E67}'
Version …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现IUnknown.我按照指示进入发球台,但它不起作用.当我尝试编译时,我得到:
Error 2 error C2695: 'testInterfaceImplementation::AddRef': overriding virtual function differs from 'IUnknown::AddRef' only by calling convention c:\users\seanm\desktop\test\test\source.cpp 6 1 test
Error 3 error C2695: 'testInterfaceImplementation::QueryInterface': overriding virtual function differs from 'IUnknown::QueryInterface' only by calling convention c:\users\seanm\desktop\test\test\source.cpp 14 1 test
Error 4 error C2695: 'testInterfaceImplementation::Release': overriding virtual function differs from 'IUnknown::Release' only by calling convention c:\users\seanm\desktop\test\test\source.cpp 22 1 test
Run Code Online (Sandbox Code Playgroud)
从这段代码:
#include <Windows.h>
#include <tchar.h>
class testInterfaceImplementation : public IUnknown {
protected:
ULONG AddRef()
{
MessageBox(NULL,
_T("TEST1"),
_T("TEST1"),
NULL);
return …Run Code Online (Sandbox Code Playgroud) 德尔福柏林10.1增加了[弱]参考.Marco Cantu的博客有一些基础知识.
对于我的测试,我创建了两个包含两个自动化对象类型的COM库.容器对象包含内容对象的列表,而内容对象包含对其容器的弱引用.
以下两个方案已经过测试并正常工作(弱引用设置为null并释放内存):
但是,当我将coclasses放在两个单独的库中时,代码会生成"无效类类型转换",删除[weak]属性时错误消失.请原谅奇数样本,其目的只是为了使问题最小化,不应该作为标准编码实践
这是第一个库.ridl文件,它定义了接口和容器的CoClass:
[
uuid(E1EE3651-A400-49BF-B5C5-006D9943B9C0),
version(1.0)
]
library DelphiIntfComLib
{
importlib("stdole2.tlb");
interface IMyContainer;
interface IMyContent;
coclass MyContainer;
[
uuid(A7EF86F7-40CD-41EE-9DA1-4D9B7B24F06B),
helpstring("Dispatch interface for MyContainer Object"),
dual,
oleautomation
]
interface IMyContainer: IDispatch
{
[id(0x000000C9)]
HRESULT _stdcall Add([in] IMyContent* AMyContent);
};
[
uuid(BFD6D976-8CEF-4264-B95A-B5DA7817F6B3),
helpstring("Dispatch interface for MyContent Object"),
dual,
oleautomation
]
interface IMyContent: IDispatch
{
[id(0x000000C9)]
HRESULT _stdcall SetWeakReferenceToContainer([in] IMyContainer* AContainer);
};
[
uuid(1F56198B-B1BE-4E11-BC78-0E6FF8E55214)
]
coclass MyContainer
{
[default] interface IMyContainer;
};
};
Run Code Online (Sandbox Code Playgroud)
这是我的容器实现
unit Unit1; …Run Code Online (Sandbox Code Playgroud)