gpt4 book ai didi

c# - 使用 Fortran DLL 进行 NUnit 测试

转载 作者:太空宇宙 更新时间:2023-11-03 18:45:14 24 4
gpt4 key购买 nike

我有一个来自 Fortran 的 ServerCom DLL。我使用 tlbimp 从可以直接从 C# 引用的 ServerCom.dll 自动生成一个 MyFortran.dll。

在 C# 类库中,我引用了 MyFortran.dll。

我创建了一个使用 MyFortran.dll 的控制台应用程序并生成了正确的 list (以便拥有一个自由互操作的 COM 环境)。

它在控制台应用程序中完美运行。

现在,我编写了一个简单的 NUnit 测试并得到了一个 COM 异常。

System.Runtime.InteropServices.COMException : Retrieving the COM class factory for component with CLSID {0FB0F699-4EF8-4732-B98E-C088825E3912} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

我该如何解决这个问题?

谢谢,阿德里安。

最佳答案

您可以使用 Activation Context API 来实现这一点。这blog post给出了所有的细节。

这是一个总结。

将以下代码粘贴到您的项目中(感谢 Spike McLarty):

/// <remarks>
/// Code from http://www.atalasoft.com/blogs/spikemclarty/february-2012/dynamically-testing-an-activex-control-from-c-and
/// </remarks>
class ActivationContext
{
static public void UsingManifestDo(string manifest, Action action)
{
UnsafeNativeMethods.ACTCTX context = new UnsafeNativeMethods.ACTCTX();
context.cbSize = Marshal.SizeOf(typeof(UnsafeNativeMethods.ACTCTX));
if (context.cbSize != 0x20)
{
throw new Exception("ACTCTX.cbSize is wrong");
}
context.lpSource = manifest;

IntPtr hActCtx = UnsafeNativeMethods.CreateActCtx(ref context);
if (hActCtx == (IntPtr)(-1))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try // with valid hActCtx
{
IntPtr cookie = IntPtr.Zero;
if (!UnsafeNativeMethods.ActivateActCtx(hActCtx, out cookie))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
try // with activated context
{
action();
}
finally
{
UnsafeNativeMethods.DeactivateActCtx(0, cookie);
}
}
finally
{
UnsafeNativeMethods.ReleaseActCtx(hActCtx);
}
}

[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
{
// Activation Context API Functions
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "CreateActCtxW")]
internal extern static IntPtr CreateActCtx(ref ACTCTX actctx);

[DllImport("Kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ActivateActCtx(IntPtr hActCtx, out IntPtr lpCookie);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie);

[DllImport("Kernel32.dll", SetLastError = true)]
internal static extern void ReleaseActCtx(IntPtr hActCtx);

// Activation context structure
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
internal struct ACTCTX
{
public Int32 cbSize;
public UInt32 dwFlags;
public string lpSource;
public UInt16 wProcessorArchitecture;
public UInt16 wLangId;
public string lpAssemblyDirectory;
public string lpResourceName;
public string lpApplicationName;
public IntPtr hModule;
}

}
}

每次需要创建 COM 对象(本例中为 COMObject)时,将创建它的调用包装在 lambda 函数中,并将其传递给 UsingManifestDo,如下所示:

object CreateManifestDependantCOMObject() 
{
object myCOMObject = null;
ActivationContext.UsingManifestDo(pathToManifestFile, () => myCOMObject = new COMObject());
return myCOMObject;
}

关于c# - 使用 Fortran DLL 进行 NUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4935536/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com