一种x64进程使用32位 DLL的方法

有的时候要用第三方的DLL,但是仅有32位版本,自己开发的程序又必须是是64位的,这下头就疼了。。。。

其实反之也是一样的头疼,这时候有什么办法呢?

一个典型的思路就是用32位进程加载DLL,然后64位进程跟32位进程通讯。

其实微软已经有了COM技术来帮我们解决这个问题:

1.创建一个进程外COM服务器。
2.使用COM服务器的相关接口去包装32位DLL的接口。

3.64位进程调用32位COM服务器接口。

这里面的关键就是如何创建一个进程外COM服务器

使用ATL模板去创建是一种非常快捷方便的方式




EXE才是进程外Com 服务,另外勾选另一个选项可以减少一个代理project

然后增加一个类作



这时候编译一下 会发现一个错误,


这是因为编译之后会去注册com组件,因为没有权限儿报错,如果使用管理员权限开vs就不会有这个问题。

接着在类中加入包裹DLL的代码

STDMETHODIMP ccleenSimple::LoadDll32()
{
	m_hDll = LoadLibrary(_T("TestDll.dll"));
	if (m_hDll)
	{
		m_pFun = (GCUN)GetProcAddress(m_hDll,"GetCurrentUserName");
		if (m_pFun != NULL)
			return S_OK;
	}
	else
		GetLastError();
	return E_FAIL;
}

STDMETHODIMP  ccleenSimple::Launch(TCHAR szTitile[MAX_PATH])
{
	HRESULT hr = LoadDll32();
	BOOL bRet = FALSE;
	TCHAR szUserName[MAX_PATH] = { 0 };
	if (Failed(hr))
	{
		OutputDebugString(_T("LoadDll32 fail"));
		MessageBox(NULL,_T("LoadDll32 fail"),_T("COMServer"),MB_OK);
	}
	else
	{
		bRet = m_pFun(szUserName);
	}
	if (bRet)
	{
		OutputDebugString(szUserName);
		MessageBox(NULL,szUserName,MB_OK);
	}
	else
	{
		MessageBox(NULL,_T("Func Failed"),MB_OK);
	}
	

	return S_OK;
}

在IDL文件中导出我们的包装函数


这样就可以了~

DLL中的函数

EXTERN_C BOOL WINAPI GetCurrentUserName(TCHAR* pszbuff)
{
	BOOL bRet = FALSE;

	TCHAR szUserNameBuffer[MAX_PATH];
	DWORD dwUserNameSize = MAX_PATH;

	bRet = GetUserName(szUserNameBuffer,&dwUserNameSize);

	if (bRet)
	{
		_tcscpy_s(pszbuff,dwUserNameSize,szUserNameBuffer);
	}

	return bRet;
}

客户端测试代码

HRESULT hr = CoInitialize(NULL);
	ICLeenSimple* pILeenTest;
	//CComPtr<ILeenTest> pILeenTest;
	TCHAR szUserName[MAX_PATH] = { 0 };
	if (SUCCEEDED(hr))
	{
		hr = CoCreateInstance(CLSID_CLeenSimple,NULL,CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,__uuidof(ICLeenSimple),(void**)&pILeenTest);
		if (SUCCEEDED(hr))
		{
			pILeenTest->Launch(szUserName);
		}
	}

测试前记得先注册COM server

命令

注册

Out_Process.exe /RegServer

反注册

Out_Process.exe /UnregServer

可以查看注册表确认是否注册成功。


运行一下,见证奇迹的时刻到啦~


代码下载链接

一种x64进程使用x86 DLL的方法的更多相关文章

  1. 在GAC之外的COM应用程序中注册.NET程序集

    我开发了一个.NET程序集(.NET4.0,强名称),它公开了两个服务组件.程序集(dll)应该托管在COM应用程序中,并使用COM属性(程序集和组件级别)进行修饰.例如,程序集级别属性:目前(开发原因),我一直在运行以下脚本来创建COM应用程序并注册程序集(包含其所有组件):上面的批处理文件将根据程序集装饰属性创建(在单次运行中)COM应用程序,在COM应用程序中注册MyComPlusAssem

  2. windows-server-2008 – COM对象丢失凭据信息

    我有一个奇怪的问题,我无法追查.我们的WindowsServer2008R2(我们的开发人员机器上的Windows7)上有一个COM组件,由ASP.net应用程序调用.有时COM组件会抛出错误:System.Runtime.InteropServices.COMException(0x8000401A):无法启动服务器进程,因为配置的标识不正确.检查用户名和密码.(HRESULT异常:0x8000

  3. 一种x64进程使用x86 DLL的方法

    一种x64进程使用32位DLL的方法有的时候要用第三方的DLL,但是仅有32位版本,自己开发的程序又必须是是64位的,这下头就疼了。。。。其实微软已经有了COM技术来帮我们解决这个问题:1.创建一个进程外COM服务器。

  4. Delphi和COM:TLB和维护问题

    在我工作的公司中,我们使用C#开发所有GUI,但应用程序内核主要是在Delphi5中开发的,在COM中制作了许多组件.与这个非常具体的应用相关,我有两个问题:>在Delphi和/或COM中经验丰富的人,你有没有工作环境来处理错误的TLB接口?一些错误是:IDE在大型TLB的编辑期间崩溃,丢失方法ID,TLB损坏等.在这里,我们还没有找到任何好的解决方案.实际上我们尝试升级做新的2007版本.但是新的IDETLB接口具有我们之前发现的相同错误.>您如何控制TLB版本?

  5. C#/ WSC(COM)互操作中的FatalExecutionEngineError

    System.Reflection.MethodBase.CheckArguments[NativetoManagedTransition]最后要注意的是:如果我为“DataProvider”类创建一个包装器,使用IReflect并将Idispatch上的调用映射到对底层“DataProvider”实例的调用,那么问题就会消失.但同样,我认为这个答案在某种程度上对我来说似乎很危险–如果我必须一丝不苟地确保传递给组件的任何引用都有这样的包装器,那么错误可能会很难追踪到.如果包含在IReflect实现包装器中

  6. 如何在Native Visual C中轻松使用COM组件

    我正在尝试构建一个在VisualStudio’05中使用COM组件的应用程序在本地C.MSDN中原生和管理的事物的混合完全毁了我的脑.我需要一个简短的原生C代码示例来加载我的Component并使其可用.我很好用编译器创建包装器等.请不要建议我使用基于对话框的MFC示例,因为它不适用于这个组件,本身就是一个巨大的组件一堆c…没有定义的标头我可以使用的接口的ID.但是我读到了c编译器可以为我提取并包装它.有谁知道这是怎么做的?

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部