本文是对Nish Sivakumar、Cuthbert Calculus教授和Glenn Quagmire共同进行的研究练习的总结。旨在探索通过多级多语言隧道装置生成确定性素数的方法。为了保持对要解决的基本问题的专注,示例代码被设计得足够简单。从内联汇编器方法开始,该方法由一个导出的C函数使用,然后被封装并作为C++类导出,再通过C++/CLI包装器暴露给CLR,最后由C# COM DLL使用,该DLL通过VBScript调用并执行命令脚本。
内联汇编是核心随机化代码,使用汇编语言编写以保持简单和轻量级。在示例中,将缓存的素数数量限制为3,因此在代码中使用了除数。
int GenerateIndex(int num) {
_asm {
mov eax, dword ptr [num]
xor edx, edx
mov ecx, 3
idiv ecx
mov eax, edx
}
}
C DLL本质上导出了一个简单的函数,该函数返回一个确定性的素数,并且内部将随机化逻辑委托给汇编代码。此时,该库可以被任何能够调用C DLL的框架或层使用。
int __stdcall DllMain() {
return 0;
}
int primes[] = {29, 37, 61};
__declspec(dllexport) int GetDetPrime() {
return primes[GenerateIndex(GetTickCount())];
}
将C DLL封装并作为C++类导出,以原生支持世界上最受欢迎的编程语言。这是一个非常薄的包装,因为不想在这一点上增加任何开销。
// 头文件
class __declspec(dllexport) CDetPrimeLib {
public:
int GetDetPrime();
};
// 实现文件
#pragma comment(lib, "DetPrime.lib")
extern "C" __declspec(dllimport) int GetDetPrime();
int CDetPrimeLib::GetDetPrime() {
return ::GetDetPrime();
}
已经提供了足够的API暴露,可以被认为是主流的,因此有一个C++/CLI包装库,它将功能暴露给托管调用者。
#pragma once
#pragma comment(lib, "DetPrimeLib.lib")
class __declspec(dllimport) CDetPrimeLib {
public:
int GetDetPrime();
};
namespace DetPrimeManWrap {
public ref class DetPrimeManaged {
CDetPrimeLib* pNative;
public:
DetPrimeManaged() {
pNative = new CDetPrimeLib();
}
~DetPrimeManaged() {
this->!DetPrimeManaged();
}
!DetPrimeManaged() {
delete pNative;
}
int GetDetPrime() {
return pNative->GetDetPrime();
}
};
}
由于支持.NET,也可以支持COM,上述C#代码正是这样做的。代码现在已经准备好供COM使用。
[assembly: ComVisible(true)]
[assembly: Guid("6b4bf847-a45d-4f87-ba53-0d4a9fffa975")]
[assembly: AssemblyVersion("1.0.1.1")]
[assembly: AssemblyFileVersion("1.0.1.1")]
namespace DetPrimeCOM {
using DetPrimeManWrap;
[Guid("18535B5E-0561-4BA8-8CF6-85B148F3A4CF")]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IDetPrime {
int GetDetPrime();
}
[Guid("2299461C-1FFB-4D5D-A521-0830F93FB5CC")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class DetPrime : IDetPrime {
public int GetDetPrime() {
return new DetPrimeManaged().GetDetPrime();
}
}
}
VB6现在已经正式灭绝,所以使用一个简单的VBScript脚本来调用COM库。
Dim detPrime
Set detPrime = CreateObject("DetPrimeCOM.DetPrime")
Wscript.Echo "The generated Deterministic Prime is " & detPrime.GetDetPrime
@%windir%\syswow64\cscript.exe /nologo DetPrime.vbs