开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 205|回复: 6
收起左侧

[易语言] C#源代码文件.CS 如何在易语言中调用?

[复制链接]
结帖率:30% (3/10)
发表于 昨天 09:33 | 显示全部楼层 |阅读模式   四川省乐山市
12精币
最近在查找如何获取AHCI base address的方法,看到利用WinRing0这个开源dll来完成这个功能。请看WinRing0API的说明

upport Functions for PCI Access
C++ (OlsDef.h) *Macro
// Bus Number, Device Number and Function Number to PCI Device Address#define PciBusDevFunc(Bus, Dev, Func) ((Bus&0xFF)<<8) | ((Dev&0x1F)<<3) | (Func&7)
// PCI Device Address to Bus Number
#define PciGetBus(address)            ((address>>8) & 0xFF)
// PCI Device Address to Device Number#define PciGetDev(address)            ((address>>3) & 0x1F)
// PCI Device Address to Function Number
#define PciGetFunc(address)           (address&7)C# (OpenLibSys.cs)
// Bus Number, Device Number and Function Number to PCI Device Addresspublic uint PciBusDevFunc(uint bus, uint dev, uint func)
{
    return ((bus&0xFF)<<8) | ((dev&0x1F)<<3) | (func&7);
}
// PCI Device Address to Bus Numberpublic uint PciGetBus(uint address)
{
    return ((address>>8) & 0xFF);
}
// PCI Device Address to Device Numberpublic uint PciGetDev(uint address)
{
    return ((address>>3) & 0x1F);
}
// PCI Device Address to Function Numberpublic uint PciGetFunc(uint address)
{
    return (address&7);
}PCI Device Address
bit description
0- 2 Function Number
3- 7 Device Number
8-15 PCI Bus Number
16-31 Reserved
Requirements
WinRing0 1.0 or later
看到了吧 我们可以用OpenLibSys.cs中现成的
PciBusDevFunc(uint bus, uint dev, uint func)
方法,就可以得到AHCI base address啦!有木有很激动?!
  附上调用的代码
/**getAHCIbaseAddress**/
        public string getAHCIbaseAddress()
        {
            uint address = ols.PciBusDevFunc(0x00, 0x1F, 0x02);

            //add by kelsey
            string ahciBaseAddress = "";

            // Host Bridge
            if (address != 0xFFFFFFFF)
            {
                for (int i = 0; i < 256; i += 16)
                {
                    //str += i.ToString("X2") + "|";
                    for (int j = 0; j < 16; j++)
                    {
                        if (i == 32 && j == 4)
                        {
                            ahciBaseAddress = (ols.ReadPciConfigDword(address, (byte)(i + j))).ToString("X2");
                            break;
                        }
                    }
                }
                Console.WriteLine("ahciBaseAddress ==" + ahciBaseAddress);
            }
            return ahciBaseAddress;
        }
然而,在易语言中,用OpenLibSys.cs,对于C#的源码文件.CS,我们应该怎么使用呢求助
附上.CS文件
Cs.zip (39.2 KB, 下载次数: 0)


回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至 源码区 可获得加分喔。
友情提醒:本版被采纳的主题可在 申请荣誉值 页面申请荣誉值,获得 1点 荣誉值,荣誉值可兑换荣誉会员、终身vip用户组。
快捷通道:申请荣誉值
结帖率:36% (4/11)

签到天数: 11 天

发表于 昨天 10:00 | 显示全部楼层   四川省成都市
.cs 文件不能直接给易语言调用。OpenLibSys.cs 本质只是 C# 对 WinRing0.dll 的封装,易语言里最简单的做法是:不要用 C#,直接声明 WinRing0.dll 的 DLL 命令。

注意哈:PciBusDevFunc() 不是 DLL 函数,只是一个地址计算公式,易语言里自己写即可。
回复

使用道具 举报

结帖率:30% (3/10)

签到天数: 6 天

 楼主| 发表于 昨天 10:14 | 显示全部楼层   四川省乐山市
juste 发表于 2026-5-26 10:00
.cs 文件不能直接给易语言调用。OpenLibSys.cs 本质只是 C# 对 WinRing0.dll 的封装,易语言里最简单的做法 ...

WinRing0.dll 没有对应的DLL  能直接写的话也不会来求助了
回复

使用道具 举报

结帖率:36% (4/11)

签到天数: 11 天

发表于 昨天 10:38 | 显示全部楼层   四川省成都市
WinRing0.dll 查看导出函数列表,然后能不能用易语言代码翻译实现PciBusDevFunc 功能了,可以的话调用 ReadPciConfigDword 读取 PCI 配置空间 0x24得到 AHCI BAR5 / ABAR

但要注意:你贴的 C# 代码有一个误区。

uint address = ols.PciBusDevFunc(0x00, 0x1F, 0x02);
这个得到的不是 AHCI base address,它只是 PCI 地址编码:

bus = 0
dev = 31
func = 2
真正的 AHCI base address 是这一句读出来的:

ols.ReadPciConfigDword(address, 0x24)
回复

使用道具 举报

结帖率:40% (2/5)

签到天数: 9 天

发表于 昨天 15:35 | 显示全部楼层   广东省揭阳市
C#和易语言交互好像com方便些
回复

使用道具 举报

结帖率:100% (10/10)
发表于 昨天 16:25 | 显示全部楼层   北京市北京市
C++ 代码封装成一个标准的 32 位 DLL,导出 PCI 地址操作和 WinRing0 初始化函数,供其他语言(如 C#、Python、VB)调用。

完整 DLL 源码
PciHelper.h

cpp
#pragma once

#ifdef PCIHELPER_EXPORTS
#define PCIHELPER_API __declspec(dllexport)
#else
#define PCIHELPER_API __declspec(dllimport)
#endif

// 初始化和清理
extern "C" PCIHELPER_API BOOL InitPciAccess();
extern "C" PCIHELPER_API void CleanupPciAccess();

// 地址转换函数
extern "C" PCIHELPER_API DWORD PciBusDevFunc(BYTE bus, BYTE dev, BYTE func);
extern "C" PCIHELPER_API BYTE PciGetBus(DWORD address);
extern "C" PCIHELPER_API BYTE PciGetDev(DWORD address);
extern "C" PCIHELPER_API BYTE PciGetFunc(DWORD address);

// PCI 读写函数
extern "C" PCIHELPER_API BOOL ReadPciDword(DWORD address, BYTE reg, DWORD* value);
extern "C" PCIHELPER_API BOOL ReadPciWord(DWORD address, BYTE reg, WORD* value);
extern "C" PCIHELPER_API BOOL ReadPciByte(DWORD address, BYTE reg, BYTE* value);
extern "C" PCIHELPER_API BOOL WritePciDword(DWORD address, BYTE reg, DWORD value);
extern "C" PCIHELPER_API BOOL WritePciWord(DWORD address, BYTE reg, WORD value);
extern "C" PCIHELPER_API BOOL WritePciByte(DWORD address, BYTE reg, BYTE value);

// 获取错误码
extern "C" PCIHELPER_API DWORD GetLastPciError();
PciHelper.cpp

cpp
#include <windows.h>
#include "PciHelper.h"
#include "OlsApi.h"  // WinRing0 头文件

static DWORD g_lastError = 0;

BOOL InitPciAccess()
{
    if (!InitializeOls())
    {
        g_lastError = GetDllStatus();
        return FALSE;
    }
    g_lastError = 0;
    return TRUE;
}

void CleanupPciAccess()
{
    DeinitializeOls();
}

DWORD PciBusDevFunc(BYTE bus, BYTE dev, BYTE func)
{
    return ((bus & 0xFF) << 8) | ((dev & 0x1F) << 3) | (func & 7);
}

BYTE PciGetBus(DWORD address)
{
    return (BYTE)((address >> 8) & 0xFF);
}

BYTE PciGetDev(DWORD address)
{
    return (BYTE)((address >> 3) & 0x1F);
}

BYTE PciGetFunc(DWORD address)
{
    return (BYTE)(address & 7);
}

BOOL ReadPciDword(DWORD address, BYTE reg, DWORD* value)
{
    g_lastError = 0;
    if (!value) return FALSE;
   
    BOOL result = ReadPciConfigDword(address, reg, value);
    if (!result) g_lastError = GetDllStatus();
    return result;
}

BOOL ReadPciWord(DWORD address, BYTE reg, WORD* value)
{
    g_lastError = 0;
    if (!value) return FALSE;
   
    BOOL result = ReadPciConfigWord(address, reg, value);
    if (!result) g_lastError = GetDllStatus();
    return result;
}

BOOL ReadPciByte(DWORD address, BYTE reg, BYTE* value)
{
    g_lastError = 0;
    if (!value) return FALSE;
   
    BOOL result = ReadPciConfigByte(address, reg, value);
    if (!result) g_lastError = GetDllStatus();
    return result;
}

BOOL WritePciDword(DWORD address, BYTE reg, DWORD value)
{
    g_lastError = 0;
    BOOL result = WritePciConfigDword(address, reg, value);
    if (!result) g_lastError = GetDllStatus();
    return result;
}

BOOL WritePciWord(DWORD address, BYTE reg, WORD value)
{
    g_lastError = 0;
    BOOL result = WritePciConfigWord(address, reg, value);
    if (!result) g_lastError = GetDllStatus();
    return result;
}

BOOL WritePciByte(DWORD address, BYTE reg, BYTE value)
{
    g_lastError = 0;
    BOOL result = WritePciConfigByte(address, reg, value);
    if (!result) g_lastError = GetDllStatus();
    return result;
}

DWORD GetLastPciError()
{
    return g_lastError;
}
编译 32 位 DLL 的步骤
Visual Studio 配置
创建项目:新建 → Visual C++ → Windows 桌面 → 动态链接库 (DLL)

设置平台为 x86:

解决方案平台下拉框 → 配置管理器 → 活动解决方案平台 → 新建

选择 x86,确定

添加 WinRing0 文件:

将 OlsDef.h、OlsApi.h 和 WinRing0.lib(32位版本)放入项目目录

项目 → 属性 → VC++ 目录 → 包含目录,添加头文件路径

项目 → 属性 → 链接器 → 输入 → 附加依赖项,添加 WinRing0.lib

定义导出宏:

项目 → 属性 → C/C++ → 预处理器 → 预处理器定义

添加 PCIHELPER_EXPORTS

编译:生成 → 生成解决方案(选择 Release x86)

运行时依赖文件
编译好的 DLL 需要配合以下文件使用 :

文件        说明
PciHelper.dll        你封装的32位DLL
WinRing0.dll        WinRing0 32位核心库
WinRing0.sys        32位内核驱动程序
注意:运行时所有文件需放在同一目录,并以管理员权限运行调用程序。

调用示例(C# 调用 32位 DLL)
csharp
using System;
using System.Runtime.InteropServices;

class PciTest
{
    [DllImport("PciHelper.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern bool InitPciAccess();
   
    [DllImport("PciHelper.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern void CleanupPciAccess();
   
    [DllImport("PciHelper.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern uint PciBusDevFunc(byte bus, byte dev, byte func);
   
    [DllImport("PciHelper.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern bool ReadPciDword(uint address, byte reg, out uint value);
   
    static void Main()
    {
        if (!InitPciAccess())
        {
            Console.WriteLine("初始化失败,请以管理员权限运行");
            return;
        }
        
        uint address = PciBusDevFunc(0, 31, 2);
        uint value;
        if (ReadPciDword(address, 0x00, out value))
        {
            Console.WriteLine($"Vendor/Device: 0x{value:X8}");
        }
        
        CleanupPciAccess();
    }
}
注意:调用方也必须编译为 x86 目标平台,才能正确加载32位 DLL
回复

使用道具 举报

结帖率:100% (6/6)

签到天数: 26 天

发表于 昨天 21:40 | 显示全部楼层   安徽省蚌埠市
废那个劲干啥呢?  没办法声明   那cs 文件 你编译C#dll  和易语言交互不就行了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备2025452707号) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表