- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
VBA 使用的 VBE7.dll 类型库具有以下 MIDL,用于 Conversion
模块:
[
dllname("VBE7.DLL"),
uuid(36785f40-2bcc-1069-82d6-00dd010edfaa),
helpcontext(0x000f6ebe)
]
module Conversion {
[helpcontext(0x000f6ea2)]
BSTR _stdcall _B_str_Hex([in] VARIANT* Number);
[helpcontext(0x000f652a)]
VARIANT _stdcall _B_var_Hex([in] VARIANT* Number);
[helpcontext(0x000f6ea4)]
BSTR _stdcall _B_str_Oct([in] VARIANT* Number);
[helpcontext(0x000f6557)]
VARIANT _stdcall _B_var_Oct([in] VARIANT* Number);
[hidden, helpcontext(0x000f6859)]
long _stdcall MacID([in] BSTR Constant);
[helpcontext(0x000f6ea9)]
BSTR _stdcall _B_str_Str([in] VARIANT* Number);
[helpcontext(0x000f658a)]
VARIANT _stdcall _B_var_Str([in] VARIANT* Number);
[helpcontext(0x000f659f)]
double _stdcall Val([in] BSTR String);
[helpcontext(0x000f64c8)]
BSTR _stdcall CStr([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
BYTE _stdcall CByte([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
VARIANT_BOOL _stdcall CBool([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
CY _stdcall CCur([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
DATE _stdcall CDate([in] VARIANT* Expression);
[helpcontext(0x000f6e7a)]
VARIANT _stdcall CVDate([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
short _stdcall CInt([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
long _stdcall CLng([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
int64 _stdcall CLngLng([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
LONG_PTR#i _stdcall CLngPtr([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
float _stdcall CSng([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
double _stdcall CDbl([in] VARIANT* Expression);
[helpcontext(0x000f64c8)]
VARIANT _stdcall CVar([in] VARIANT* Expression);
[helpcontext(0x000f64b5)]
VARIANT _stdcall CVErr([in] VARIANT* Expression);
[helpcontext(0x000f6c6d)]
BSTR _stdcall _B_str_Error([in, optional] VARIANT* ErrorNumber);
[helpcontext(0x000f6c6d)]
VARIANT _stdcall _B_var_Error([in, optional] VARIANT* ErrorNumber);
[helpcontext(0x000f649b)]
VARIANT _stdcall Fix([in] VARIANT* Number);
[helpcontext(0x000f6533)]
VARIANT _stdcall Int([in] VARIANT* Number);
[helpcontext(0x000f64c8)]
HRESULT _stdcall CDec(
[in] VARIANT* Expression,
[out, retval] VARIANT* pvar
);
};
HRESULT
特别感兴趣的地方返回
CDec
函数(上面 MIDL 中的最后一个函数),这样在 VBA 中,
CDec
函数有一个签名
Function CDec(Expression)
HRESULT
返回 TLB 定义,因此为了测试理论,我想创建自己的 TLB 来定义
HRESULT
module
中的返回函数,然后查看 VBA 如何处理该函数。
VBA
,因为我正在尝试从 C# 解释 TLB。为了测试 VBA 主机如何解释 TLB,我想用支持它的任何语言创建一个合适的 TLB。我可以使用 Visual Studio 6、2003、2013 和 2015。
最佳答案
CDec 声明中重要的是 [out] and [retval] attributes 组合。
理解它的工具(如 VB/VBA)将能够以简化的方式编译对此方法的调用,屏蔽错误处理,因此
HRESULT _stdcall CDec(
[in] VARIANT* Expression,
[out, retval] VARIANT* pvar
);
VARIANT _stdcall CDec([in] VARIANT* Expression);
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Class1
{
public object Test(object obj)
{
return obj;
}
}
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm "C:\mypath\ClassLibrary1\bin\Debug\classlibrary1.dll" /tlb /codebase
C:\mypath\ClassLibrary1\bin\Debug\classlibrary1.tlb
类型库文件。
ClassLibrary1.dll
编译方式相同的位数运行。
Sub Button1_Click()
Dim c1 As New Class1
output = c1.Test("hello from VB")
End Sub
#include "stdafx.h" // needs Windows.h
#import "c:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscorlib.tlb" // adapt to your context
#import "C:\\mypath\\ClassLibrary1\\bin\\Debug\\classlibrary1.tlb"
using namespace ClassLibrary1;
int main()
{
CoInitialize(NULL);
_Class1Ptr c1(__uuidof(Class1));
_variant_t output = c1->Test(L"hello from C++");
wprintf(L"output: %s\n", V_BSTR(&output));
CoUninitialize();
return 0;
}
Test
调用并执行 Goto Definition (F12),这是我们看到的:
inline _variant_t _Class1::Test ( const _variant_t & obj ) {
VARIANT _result;
VariantInit(&_result);
HRESULT _hr = raw_Test(obj, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _variant_t(_result, false);
}
_Class1Ptr
上执行 F12 ,您将看到(简化):
_Class1 : IDispatch
{
// Wrapper methods for error-handling
...
_variant_t Test (
const _variant_t & obj );
...
// Raw methods provided by interface
...
virtual HRESULT __stdcall raw_Test (
/*[in]*/ VARIANT obj,
/*[out,retval]*/ VARIANT * pRetVal ) = 0;
};
Test
方法符合预期的
[out, retval]
形式。剩下的都是糖和 wrapper 。
CDec
的定义与 VBE7 中的其他方法不同。我没有答案。
module
关键字,IDL 只是一个抽象定义(函数、常量、类等)工具,可以选择性地输出针对特定语言的人工制品(.H、.C、.TLB 等)( C/C++ 等)或针对特定客户端。
my.idl
文件:
[
uuid(00001234-0001-0000-0000-012345678901)
]
library MyLib
{
[
uuid(00001234-0002-0000-0000-012345678901),
dllname("kernel32.dll")
]
module MyModule
{
const int MyConst = 1234;
// note this is the real GetCurrentThreadId from kernel32.dll
[entry("GetCurrentThreadId")]
int GetCurrentThreadId();
}
}
midl c:\mypath\my.idl /out c:\mypath
my.tlb
文件,您可以在 VB/VBA 中引用该文件。现在,从 VB/VBA 中,您可以使用一个名为
GetCurrentThreadId
的新函数(intellisense 可以处理它)。它之所以有效,是因为 Windows 的 kernel32.dll 确实导出了一个
GetCurrentThreadId 函数。
关于c++ - 如何在 COM 类型库中创建模块定义的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44510639/
COM 内存泄漏最常见的原因是什么? 我读过将初始化的 CComBSTR 的地址作为 [out] 参数传递给函数会导致泄漏。我正在寻找像这样枚举其他常见的编程错误。 最佳答案 未能为 COM 对象使用
在COM服务器执行过程中分配一 block 内存,然后通过一个输出参数将该内存块传递给客户端是很常见的。然后,客户端有义务使用 CoTaskMemFree() 等方法释放该内存。 问题是,这 bloc
我有一些 MFC 代码(自定义 CWnd 控件和一些要公开的类),我需要将它们制作成带有接口(interface)的 activex/COM 对象。使用 MFC 支持制作 ATL 项目并以这种方式制作
Devenv.com 是 visual studio 命令行界面,当您键入 devenv/? 时,devenv 的帮助会出现在控制台上。但是,如果没有任何选项,devenv.com 只会调用 deve
如何将 COM 接口(interface)的引用作为 COM 库中的参数传递? 这是示例: 1)客户端代码成功创建coclass并接收到pFunctionDiscovery中的接口(interface
我正在使用 django,我在 s3 中存储了诸如 imgs 之类的东西(为此我使用的是 boto),但最近我收到了这个错误: 'foo.bar.com.s3.amazonaws.com' doesn
我已经使用组件服务 MSC 对话框创建了一个 COM+ 应用程序。我将一个现有的 COM 对象导入到这个新的 COM+ 应用程序中。 我知道可以通过 COM+ 应用程序调用该 COM 对象。我可以简单
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 11 年前。 Improve thi
我正在使用通过 COM Interop 包装器公开的第三方 dll。但是,其中一个 COM 调用经常卡住(至少从不返回)。为了至少让我的代码更健壮一些,我异步包装了调用(_getDeviceInfoW
很多年前我读到有一个简单的 php 脚本可以将您的网站重定向到 http://example.com/google.com 到 google.com它适用于正斜杠右侧的任何域。我忘记了这个脚本是什么或
我正在实现我的第一个进程外 COM 服务器(我的第一个 COM 服务器,就此而言)。我已经按照步骤编写了一个 IDL 文件,为代理/ stub DLL 生成代码,编译 DLL,并注册它。 当我检查注册
是否可以在未知接口(interface)上增加 RCW 引用计数? (即不是底层 COM 对象的引用计数) 我有一些旧的 COM 服务器代码 int Method1(object comobject)
我注意到许多关于 COM 的书籍等都指出,在 COM 聚合中实现一个可用作内部对象的对象相对容易。但是,除非我遗漏了什么,否则聚合似乎只能在极其有限的场景中成功,因此只有在明确识别出这种场景时才应提供
假设我正在开发一个安装 COM 组件并安装程序注册它们的应用程序。这很好用。 现在该软件需要从内存棒上运行。如何注册我的库运行时并确保在运行应用程序后清理注册表? 最佳答案 您总是在 XP 或更高版本
我们已经使用Microsoft的ActiveX/COM(VB6)技术开发了一个软件系统。去年,我对自动化构建过程和整个SCM越来越感兴趣。我集中搜索了网络的大部分内容,以获取有关如何使用基于COM的软
我对 com 线程模型有点困惑。 我有一个 inproc 服务器,我想创建一个可从任何线程访问的接口(interface),而不管 CoInitializeEx 中使用的线程模型和/或标志。 当将接口
我的包以旁加载方式安装,并不断遇到特定于应用程序的权限错误。 是的,许多人建议在 regedit 和组件服务中手动更改权限和所有者。 我的应用实际上在组件服务(DCOMCNFG、DCOMCNFG -3
我正在使用第三方应用程序,并调用创建 的实例。我的 COM 对象。这个调用成功了,但是第三方应用程序上的函数没有返回指向创建对象的指针(我不知道为什么)。有没有办法获得指向我的对象的指针? 为了澄清,
我有一个用 C# 编写的托管 COM 对象和一个用 C++(MFC 和 ATL)编写的 native COM 客户端和接收器。客户端创建对象并在启动时向其事件接口(interface)提供建议,并在其
我的应用程序需要注册两个 COM DLL。如果用户有必要的访问权限,它会自动完成,否则可以使用 regsvr32 完成。 . 现在在一些工作站上会发生以下情况: 开始cmd.exe作为管理员 注册第一
我是一名优秀的程序员,十分优秀!