native C++ 动态调用.NET DLL

关于这个问题找了好多地方,都只有第二种解决办法,可是我要返回一个字符串,没办法,继续找,最后还是在http://blogs.msdn.com/b/msdnforum/archive/2010/07/09/use-clr4-hosting-api-to-invoke-net-assembly-from-native-c.aspx找到了解决的办法,这里记下来备忘。

转发下范例包:http://files.cnblogs.com/files/maintell/Cpp_app_hosts_CLR_4_and_invokes_.NET_assembly_%28CppHostCLR%29.zip

第一种可以返回一个任意变量或者对象,第二种简单点,只能返回整型,具体看代码:

  1 //
  2 //   FUNCTION: RuntimeHostV4Demo1(PCWSTR, PCWSTR)
  3 //
  4 //   PURPOSE: The function demonstrates using .NET Framework 4.0 Hosting
  5 //   Interfaces to host a .NET runtime, and use the ICorRuntimeHost interface
  6 //   that was provided in .NET v1.x to load a .NET assembly and invoke its
  7 //   type.
  8 //
  9 //   If the .NET runtime specified by the pszVersion parameter cannot be
 10 //   loaded into the current process, the function prints ".NET runtime <the
 11 //   runtime version> cannot be loaded", and return.
 12 //
 13 //   If the .NET runtime is successfully loaded, the function loads the
 14 //   assembly identified by the pszAssemblyName parameter. Next, the function
 15 //   instantiates the class (pszClassName) in the assembly, calls its
 16 //   ToString() member method, and print the result. Last, the demo invokes
 17 //   the public static function ‘int GetStringLength(string str)‘ of the class
 18 //   and print the result too.
 19 //
 20 //   PARAMETERS:
 21 //   * pszVersion - The desired DOTNETFX version, in the format “vX.X.XXXXX”.
 22 //     The parameter must not be NULL. It’s important to note that this
 23 //     parameter should match exactly the directory names for each version of
 24 //     the framework, under C:\Windows\Microsoft.NET\Framework[64]. The
 25 //     current possible values are "v1.0.3705", "v1.1.4322", "v2.0.50727" and
 26 //     "v4.0.30319". Also, note that the “v” prefix is mandatory.
 27 //   * pszAssemblyName - The display name of the assembly to be loaded, such
 28 //     as "CSClassLibrary". The ".DLL" file extension is not appended.
 29 //   * pszClassName - The name of the Type that defines the method to invoke.
 30 //
 31 //   RETURN VALUE: HRESULT of the demo.
 32 //
 33 HRESULT RuntimeHostV4Demo1(PCWSTR pszVersion, PCWSTR pszAssemblyName,
 34     PCWSTR pszClassName)
 35 {
 36     HRESULT hr;
 37
 38     ICLRMetaHost *pMetaHost = NULL;
 39     ICLRRuntimeInfo *pRuntimeInfo = NULL;
 40
 41     // ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting interfaces
 42     // supported by CLR 4.0. Here we demo the ICorRuntimeHost interface that
 43     // was provided in .NET v1.x, and is compatible with all .NET Frameworks.
 44     ICorRuntimeHost *pCorRuntimeHost = NULL;
 45
 46     IUnknownPtr spAppDomainThunk = NULL;
 47     _AppDomainPtr spDefaultAppDomain = NULL;
 48
 49     // The .NET assembly to load.
 50     bstr_t bstrAssemblyName(pszAssemblyName);
 51     _AssemblyPtr spAssembly = NULL;
 52
 53     // The .NET class to instantiate.
 54     bstr_t bstrClassName(pszClassName);
 55     _TypePtr spType = NULL;
 56     variant_t vtObject;
 57     variant_t vtEmpty;
 58
 59     // The static method in the .NET class to invoke.
 60     bstr_t bstrStaticMethodName(L"GetStringLength");
 61     SAFEARRAY *psaStaticMethodArgs = NULL;
 62     variant_t vtStringArg(L"HelloWorld");
 63     variant_t vtLengthRet;
 64
 65     // The instance method in the .NET class to invoke.
 66     bstr_t bstrMethodName(L"ToString");
 67     SAFEARRAY *psaMethodArgs = NULL;
 68     variant_t vtStringRet;
 69
 70     //
 71     // Load and start the .NET runtime.
 72     //
 73
 74     wprintf(L"Load and start the .NET runtime %s \n", pszVersion);
 75
 76     hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
 77     if (FAILED(hr))
 78     {
 79         wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
 80         goto Cleanup;
 81     }
 82
 83     // Get the ICLRRuntimeInfo corresponding to a particular CLR version. It
 84     // supersedes CorBindToRuntimeEx with STARTUP_LOADER_SAFEMODE.
 85     hr = pMetaHost->GetRuntime(pszVersion, IID_PPV_ARGS(&pRuntimeInfo));
 86     if (FAILED(hr))
 87     {
 88         wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
 89         goto Cleanup;
 90     }
 91
 92     // Check if the specified runtime can be loaded into the process. This
 93     // method will take into account other runtimes that may already be
 94     // loaded into the process and set pbLoadable to TRUE if this runtime can
 95     // be loaded in an in-process side-by-side fashion.
 96     BOOL fLoadable;
 97     hr = pRuntimeInfo->IsLoadable(&fLoadable);
 98     if (FAILED(hr))
 99     {
100         wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
101         goto Cleanup;
102     }
103
104     if (!fLoadable)
105     {
106         wprintf(L".NET runtime %s cannot be loaded\n", pszVersion);
107         goto Cleanup;
108     }
109
110     // Load the CLR into the current process and return a runtime interface
111     // pointer. ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting
112     // interfaces supported by CLR 4.0. Here we demo the ICorRuntimeHost
113     // interface that was provided in .NET v1.x, and is compatible with all
114     // .NET Frameworks.
115     hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,
116         IID_PPV_ARGS(&pCorRuntimeHost));
117     if (FAILED(hr))
118     {
119         wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
120         goto Cleanup;
121     }
122
123     // Start the CLR.
124     hr = pCorRuntimeHost->Start();
125     if (FAILED(hr))
126     {
127         wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr);
128         goto Cleanup;
129     }
130
131     //
132     // Load the NET assembly. Call the static method GetStringLength of the
133     // class CSSimpleObject. Instantiate the class CSSimpleObject and call
134     // its instance method ToString.
135     //
136
137     // The following C++ code does the same thing as this C# code:
138     //
139     //   Assembly assembly = AppDomain.CurrentDomain.Load(pszAssemblyName);
140     //   object length = type.InvokeMember("GetStringLength",
141     //       BindingFlags.InvokeMethod | BindingFlags.Static |
142     //       BindingFlags.Public, null, null, new object[] { "HelloWorld" });
143     //   object obj = assembly.CreateInstance("CSClassLibrary.CSSimpleObject");
144     //   object str = type.InvokeMember("ToString",
145     //       BindingFlags.InvokeMethod | BindingFlags.Instance |
146     //       BindingFlags.Public, null, obj, new object[] { });
147
148     // Get a pointer to the default AppDomain in the CLR.
149     hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
150     if (FAILED(hr))
151     {
152         wprintf(L"ICorRuntimeHost::GetDefaultDomain failed w/hr 0x%08lx\n", hr);
153         goto Cleanup;
154     }
155
156     hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));
157     if (FAILED(hr))
158     {
159         wprintf(L"Failed to get default AppDomain w/hr 0x%08lx\n", hr);
160         goto Cleanup;
161     }
162
163     // Load the .NET assembly.
164     wprintf(L"Load the assembly %s\n", pszAssemblyName);
165     hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);
166     if (FAILED(hr))
167     {
168         wprintf(L"Failed to load the assembly w/hr 0x%08lx\n", hr);
169         goto Cleanup;
170     }
171
172     // Get the Type of CSSimpleObject.
173     hr = spAssembly->GetType_2(bstrClassName, &spType);
174     if (FAILED(hr))
175     {
176         wprintf(L"Failed to get the Type interface w/hr 0x%08lx\n", hr);
177         goto Cleanup;
178     }
179
180     // Call the static method of the class:
181     //   public static int GetStringLength(string str);
182
183     // Create a safe array to contain the arguments of the method. The safe
184     // array must be created with vt = VT_VARIANT because .NET reflection
185     // expects an array of Object - VT_VARIANT. There is only one argument,
186     // so cElements = 1.
187     psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
188     LONG index = 0;
189     hr = SafeArrayPutElement(psaStaticMethodArgs, &index, &vtStringArg);
190     if (FAILED(hr))
191     {
192         wprintf(L"SafeArrayPutElement failed w/hr 0x%08lx\n", hr);
193         goto Cleanup;
194     }
195
196     // Invoke the "GetStringLength" method from the Type interface.
197     hr = spType->InvokeMember_3(bstrStaticMethodName, static_cast<BindingFlags>(
198         BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public),
199         NULL, vtEmpty, psaStaticMethodArgs, &vtLengthRet);
200     if (FAILED(hr))
201     {
202         wprintf(L"Failed to invoke GetStringLength w/hr 0x%08lx\n", hr);
203         goto Cleanup;
204     }
205
206     // Print the call result of the static method.
207     wprintf(L"Call %s.%s(\"%s\") => %s\n",
208         static_cast<PCWSTR>(bstrClassName),
209         static_cast<PCWSTR>(bstrStaticMethodName),
210         static_cast<PCWSTR>(vtStringArg.bstrVal),
211         vtLengthRet.lVal);
212
213     // Instantiate the class.
214     hr = spAssembly->CreateInstance(bstrClassName, &vtObject);
215     if (FAILED(hr))
216     {
217         wprintf(L"Assembly::CreateInstance failed w/hr 0x%08lx\n", hr);
218         goto Cleanup;
219     }
220
221     // Call the instance method of the class.
222     //   public string ToString();
223
224     // Create a safe array to contain the arguments of the method.
225     psaMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 0);
226
227     // Invoke the "ToString" method from the Type interface.
228     hr = spType->InvokeMember_3(bstrMethodName, static_cast<BindingFlags>(
229         BindingFlags_InvokeMethod | BindingFlags_Instance | BindingFlags_Public),
230         NULL, vtObject, psaMethodArgs, &vtStringRet);
231     if (FAILED(hr))
232     {
233         wprintf(L"Failed to invoke ToString w/hr 0x%08lx\n", hr);
234         goto Cleanup;
235     }
236
237     // Print the call result of the method.
238     wprintf(L"Call %s.%s() => %s\n",
239         static_cast<PCWSTR>(bstrClassName),
240         static_cast<PCWSTR>(bstrMethodName),
241         static_cast<PCWSTR>(vtStringRet.bstrVal));
242
243 Cleanup:
244
245     if (pMetaHost)
246     {
247         pMetaHost->Release();
248         pMetaHost = NULL;
249     }
250     if (pRuntimeInfo)
251     {
252         pRuntimeInfo->Release();
253         pRuntimeInfo = NULL;
254     }
255     if (pCorRuntimeHost)
256     {
257         // Please note that after a call to Stop, the CLR cannot be
258         // reinitialized into the same process. This step is usually not
259         // necessary. You can leave the .NET runtime loaded in your process.
260         //wprintf(L"Stop the .NET runtime\n");
261         //pCorRuntimeHost->Stop();
262
263         pCorRuntimeHost->Release();
264         pCorRuntimeHost = NULL;
265     }
266
267     if (psaStaticMethodArgs)
268     {
269         SafeArrayDestroy(psaStaticMethodArgs);
270         psaStaticMethodArgs = NULL;
271     }
272     if (psaMethodArgs)
273     {
274         SafeArrayDestroy(psaMethodArgs);
275         psaMethodArgs = NULL;
276     }
277
278     return hr;
279 }

第二种比较简单:

  1 //
  2 //   FUNCTION: RuntimeHostV4Demo2(PCWSTR, PCWSTR)
  3 //
  4 //   PURPOSE: The function demonstrates using .NET Framework 4.0 Hosting
  5 //   Interfaces to host a .NET runtime, and use the ICLRRuntimeHost interface
  6 //   that was provided in .NET v2.0 to load a .NET assembly and invoke its
  7 //   type. Because ICLRRuntimeHost is not compatible with .NET runtime v1.x,
  8 //   the requested runtime must not be v1.x.
  9 //
 10 //   If the .NET runtime specified by the pszVersion parameter cannot be
 11 //   loaded into the current process, the function prints ".NET runtime <the
 12 //   runtime version> cannot be loaded", and return.
 13 //
 14 //   If the .NET runtime is successfully loaded, the function loads the
 15 //   assembly identified by the pszAssemblyName parameter. Next, the function
 16 //   invokes the public static function ‘int GetStringLength(string str)‘ of
 17 //   the class and print the result.
 18 //
 19 //   PARAMETERS:
 20 //   * pszVersion - The desired DOTNETFX version, in the format “vX.X.XXXXX”.
 21 //     The parameter must not be NULL. It’s important to note that this
 22 //     parameter should match exactly the directory names for each version of
 23 //     the framework, under C:\Windows\Microsoft.NET\Framework[64]. Because
 24 //     the ICLRRuntimeHost interface does not support the .NET v1.x runtimes,
 25 //     the current possible values of the parameter are "v2.0.50727" and
 26 //     "v4.0.30319". Also, note that the “v” prefix is mandatory.
 27 //   * pszAssemblyPath - The path to the Assembly to be loaded.
 28 //   * pszClassName - The name of the Type that defines the method to invoke.
 29 //
 30 //   RETURN VALUE: HRESULT of the demo.
 31 //
 32 HRESULT RuntimeHostV4Demo2(PCWSTR pszVersion, PCWSTR pszAssemblyPath,
 33     PCWSTR pszClassName)
 34 {
 35     HRESULT hr;
 36
 37     ICLRMetaHost *pMetaHost = NULL;
 38     ICLRRuntimeInfo *pRuntimeInfo = NULL;
 39
 40     // ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting interfaces
 41     // supported by CLR 4.0. Here we demo the ICLRRuntimeHost interface that
 42     // was provided in .NET v2.0 to support CLR 2.0 new features.
 43     // ICLRRuntimeHost does not support loading the .NET v1.x runtimes.
 44     ICLRRuntimeHost *pClrRuntimeHost = NULL;
 45
 46     // The static method in the .NET class to invoke.
 47     PCWSTR pszStaticMethodName = L"GetStringLength";
 48     PCWSTR pszStringArg = L"HelloWorld";
 49     DWORD dwLengthRet;
 50
 51     //
 52     // Load and start the .NET runtime.
 53     //
 54
 55     wprintf(L"Load and start the .NET runtime %s \n", pszVersion);
 56
 57     hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
 58     if (FAILED(hr))
 59     {
 60         wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
 61         goto Cleanup;
 62     }
 63
 64     // Get the ICLRRuntimeInfo corresponding to a particular CLR version. It
 65     // supersedes CorBindToRuntimeEx with STARTUP_LOADER_SAFEMODE.
 66     hr = pMetaHost->GetRuntime(pszVersion, IID_PPV_ARGS(&pRuntimeInfo));
 67     if (FAILED(hr))
 68     {
 69         wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
 70         goto Cleanup;
 71     }
 72
 73     // Check if the specified runtime can be loaded into the process. This
 74     // method will take into account other runtimes that may already be
 75     // loaded into the process and set pbLoadable to TRUE if this runtime can
 76     // be loaded in an in-process side-by-side fashion.
 77     BOOL fLoadable;
 78     hr = pRuntimeInfo->IsLoadable(&fLoadable);
 79     if (FAILED(hr))
 80     {
 81         wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
 82         goto Cleanup;
 83     }
 84
 85     if (!fLoadable)
 86     {
 87         wprintf(L".NET runtime %s cannot be loaded\n", pszVersion);
 88         goto Cleanup;
 89     }
 90
 91     // Load the CLR into the current process and return a runtime interface
 92     // pointer. ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting
 93     // interfaces supported by CLR 4.0. Here we demo the ICLRRuntimeHost
 94     // interface that was provided in .NET v2.0 to support CLR 2.0 new
 95     // features. ICLRRuntimeHost does not support loading the .NET v1.x
 96     // runtimes.
 97     hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
 98         IID_PPV_ARGS(&pClrRuntimeHost));
 99     if (FAILED(hr))
100     {
101         wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
102         goto Cleanup;
103     }
104
105     // Start the CLR.
106     hr = pClrRuntimeHost->Start();
107     if (FAILED(hr))
108     {
109         wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr);
110         goto Cleanup;
111     }
112
113     //
114     // Load the NET assembly and call the static method GetStringLength of
115     // the type CSSimpleObject in the assembly.
116     //
117
118     wprintf(L"Load the assembly %s\n", pszAssemblyPath);
119
120     // The invoked method of ExecuteInDefaultAppDomain must have the
121     // following signature: static int pwzMethodName (String pwzArgument)
122     // where pwzMethodName represents the name of the invoked method, and
123     // pwzArgument represents the string value passed as a parameter to that
124     // method. If the HRESULT return value of ExecuteInDefaultAppDomain is
125     // set to S_OK, pReturnValue is set to the integer value returned by the
126     // invoked method. Otherwise, pReturnValue is not set.
127     hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(pszAssemblyPath,
128         pszClassName, pszStaticMethodName, pszStringArg, &dwLengthRet);
129     if (FAILED(hr))
130     {
131         wprintf(L"Failed to call GetStringLength w/hr 0x%08lx\n", hr);
132         goto Cleanup;
133     }
134
135     // Print the call result of the static method.
136     wprintf(L"Call %s.%s(\"%s\") => %d\n", pszClassName, pszStaticMethodName,
137         pszStringArg, dwLengthRet);
138
139 Cleanup:
140
141     if (pMetaHost)
142     {
143         pMetaHost->Release();
144         pMetaHost = NULL;
145     }
146     if (pRuntimeInfo)
147     {
148         pRuntimeInfo->Release();
149         pRuntimeInfo = NULL;
150     }
151     if (pClrRuntimeHost)
152     {
153         // Please note that after a call to Stop, the CLR cannot be
154         // reinitialized into the same process. This step is usually not
155         // necessary. You can leave the .NET runtime loaded in your process.
156         //wprintf(L"Stop the .NET runtime\n");
157         //pClrRuntimeHost->Stop();
158
159         pClrRuntimeHost->Release();
160         pClrRuntimeHost = NULL;
161     }
162
163     return hr;
164 }

时间: 2024-10-31 01:05:58

native C++ 动态调用.NET DLL的相关文章

# 中静态调用C++dll 和C# 中动态调用C++dll

C# 中静态调用C++dll 和C# 中动态调用C++dll 在最近的项目中,牵涉到项目源代码保密问题,由于代码是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能反编译.这样一来,就涉及C#托管代码与C++非托管代码互相调用,于是调查了一些资料,顺便与大家分享一下: 一. C# 中静态调用C++动态链接 1. 建立VC工程CppDemo,建立的时候选择Win32 Console(dll),选择Dl

C# 中静态调用C++dll 和C# 中动态调用C++dll

C# 中静态调用C++dll 和C# 中动态调用C++dll 在最近的项目中,牵涉到项目源代码保密问题,由于代码是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能反编译.这样一来,就涉及C#托管代码与C++非托管代码互相调用,于是调查了一些资料,顺便与大家分享一下: 一. C# 中静态调用C++动态链接 1. 建立VC工程CppDemo,建立的时候选择Win32 Console(dll),选择Dl

C#程序实现动态调用DLL的研究(转)

摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资源中释放出来,通过静态加载延迟实现DLL函数的动态加载,程序退出后实现临时文件的自动删除,从而为解决“DLL Hell”提供了一种解决方案.这是一个很好的设计思想,而且该作者也用C++实现了,在Internet上也有相似的VB程序,但在某一技术论坛上提起这种设计方法时,有网友提出:“这种方法好是好,但就是启动

C#程序实现动态调用DLL的研究

原文:C#程序实现动态调用DLL的研究 摘  要:在<csdn开发高手>2004年第03期中的<化功大法--将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资源中释放出来,通过静态加载延迟实现DLL函数的动态加载,程序退出后实现临时文件的自动删除,从而为解决"DLL Hell"提供了一种解决方案.这是一个很好的设计思想,而且该作者也用C++实现了,在Internet上也有相似的VB程序,但在某一技术论坛

C#程序实现动态调用DLL的研究[转]

摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资源中释放出来,通过静态加载延迟实现DLL函数的动态加载,程序退出后实现临时文件的自动删除,从而为解决“ DLL Hell ”提供了一种解决方案.这是一个很好的设计思想,而且该作者也用 C++ 实现了,在 Internet 上也有相似的 VB 程序,但在某一技术论坛上提起这种设计方法时

C#调用外部DLL介绍及使用详解

一.      DLL与应用程序 动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现. 动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法.注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根

Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Application 有何妙用: 5. MJ0011 关于 Native Application 的文章整理: 6. 互联网上其他关于 Native Application 的文章整理: 7. 小结: 1. 引子: 其实在好久以前就看了 MJ0011 翻译的那个<Native 应用程序详细>系列的文

动态调用DLL函数有时正常,有时报Access violation的异常

动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() { hInst=LoadLibraryA("aimdtl.dll"); (FARPROC &)add=GetProcAddress(hInst,"add"); add(1,2); } 按这个代码执行,add函数有时OK,有时报Access violation的异常.看到提示,第一反应就是内存异常

MFC动态调用dll到指定的进程中(win7系统vs2013环境下)

一.主程序 1.新建一个MFC项目,类型选择基于对话框 2.写一个简单的窗体 点击启动事件 MessageBox(L"调用Dll到程序中成功."); 二.要调用的Dll 1.新建一个win32dll 选择dll.勾选导出符号 1.生成Dll项目 此时会在主程序Main的debug文件夹中生成了Dll.dll和Dll.lib文件 三.配置主程序Main的属性 1.选择链接器--输入--附加依赖项:Dll.lib 1.选择连接器--输入--常规--附加库目录:..\Debug 1.包含头文