最近我一直在尝试实现一些从InfoPath XSN文件(.CAB存档)中提取文件的功能.在广泛搜索互联网之后,似乎没有本地.NET API.所有当前的解决方案都围绕着大型库,即托管的C++,它包含了Cabinet.dll.
可悲的是,所有这些都违反了我的公司"没有第三方图书馆"的政策.
从2.0开始,.NET获得了一个名为UnmanagedFunctionPointer的属性,该属性允许使用__cdecl进行源级回调声明.在此之前,__ stdcall是镇上唯一的节目,除非你不介意捏造IL,这种做法在这里也是非法的.我立即知道这将允许为Cabinet.dll实现一个相当小的C#包装器,但我无法在任何地方找到一个示例.
有没有人知道使用本机代码执行此操作的方式比下面更清晰?
我当前的解决方案(执行非托管代码,但完全正常,在32/64位上测试):
[StructLayout(LayoutKind.Sequential)]
public class CabinetInfo //Cabinet API: "FDCABINETINFO"
{
public int cbCabinet;
public short cFolders;
public short cFiles;
public short setID;
public short iCabinet;
public int fReserve;
public int hasprev;
public int hasnext;
}
public class CabExtract : IDisposable
{
//If any of these classes end up with a different size to its C equivilent, we end up with crash and burn.
[StructLayout(LayoutKind.Sequential)]
private class CabError //Cabinet API: "ERF"
{
public int erfOper; …Run Code Online (Sandbox Code Playgroud) 背景...
我目前正在尝试将 MCS-48(没有硬件除法)的汇编例程从当前的 8 位商扩展到 16 位商
这是这里原始例程的扫描:http : //techmattmillman.s3.amazonaws.com/wp-content/uploads/2020/10/isisdiv.png
(是的,那是来自点阵打印机)。我已忠实地将其翻译为“C”代码,并已验证它的工作方式与原始代码相同:
uint8_t mcs48_divide(uint16_t dividend, uint8_t divisor, uint8_t *remainder)
{
if ((dividend >> 8) >= divisor)
goto mcs48_div_exit; // Impossible. Result would overflow. Bail.
for (int i = 0; i < 8; i++) // One pass for each bit of result
{
uint8_t msb;
uint8_t bit15_was_set = 0;
if (dividend & 0x8000)
bit15_was_set = 1; // Note if this was set, can't check if after shift.
dividend <<= 1; // …Run Code Online (Sandbox Code Playgroud)