C#中简化的类似于C宏的函数调用

阿尔帕斯兰

我正在为C dll写一个包装器。为C#应用程序包装了各种C函数。现在考虑下面包装的一些简化部分。

public enum ErrorCode
{
    OK = 0,
    ...
    ...
}

public class AppException: ApplicationException
{
    public AppException(ErrorCode errorCode) : base()
    {
        error = errorCode;
    }

    public ErrorCode error { get; private set; }
}

public class A
{
    public ErrorCode last_ret;
    private IntPtr datap;

    public A(string filename)
    {
        last_ret = (ErrorCode)ClibDllFunc1(filename, out datap);
        if (last_ret != ErrorCode.OK)
            throw new AppException(last_ret);

        // go on processing

        last_ret = (ErrorCode)ClibDllFunc2(datap);
        if (last_ret != ErrorCode.OK)
            throw new AppException(last_ret);
    }

    public void getSize(out int sz)
    {
        last_ret = (ErrorCode)ClibDllFunc3(datap, out sz);
        if (last_ret != ErrorCode.OK)
            throw new AppException(last_ret);
    }

    // ...
    // many functions like these, all working by calling c/c++ dll functions
    // with different number and types of parameters
}

[DllImport("clibrary.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern internal int ClibDllFunc1(string filename, out IntPtr data);

// ... other C function declarations follow similarly

如您所见,包装程序调用了各种C函数。所有C函数都将整数作为状态码(ErrorCode)返回,并且包装程序必须检查此返回码,并在C函数失败时引发应用程序定义的异常。对于所有C函数调用,必须以完全相同的方式完成此操作。仅函数名称和参数会更改,但三行调用块相同。这种形式的复制/粘贴三行函数调用看起来很便宜。

在C#中,是否有一种方法可以以更简单,更紧凑的方式来简化和封装“调用,检查返回代码,引发异常”循环?

供参考(实际上,这是我想简化的操作);在C / C ++中,我们可以定义这样的宏:

#define SAFE_CALL(call) do{ if((last_ret = (ErrorCode)call) != OK) throw AppException(last_ret); }while(0)

并这样调用:

SAFE_CALL(ClibDllFunc1(filename, &datap));
SAFE_CALL(ClibDllFunc2(datap));
SAFE_CALL(ClibDllFunc3(datap, &sz));
史蒂夫·霍华德

编辑

重读您的问题,我回答了错误的问题。您真正想要的是一个带有int的CheckErrorCode函数,然后只需传递本机调用的结果即可。

/// <summary>
/// Takes the result code from invoking a native function.  If the result is
/// not ErrorCode.OK, throws an AppException with that error code.
/// </summary>
/// <param name="returnCodeInt">
/// The return code of a native method call, as an integer. 
/// Will be cast to ErrorCode.
/// </param>
private static void CheckErrorCode(int returnCodeInt)
{
    ErrorCode returnCode = (ErrorCode)returnCodeInt;
    if(returnCode != ErrorCode.OK)
    {
        throw new AppException(returnCode);
    }
}

public void getSize(out int sz)
{
    CheckErrorCode(ClibDllFunc3(datap, out sz));
}

原始文本(如何使用lambdas模拟宏)

C#中的lambda语法非常简洁,这意味着您可以使用Func<T>与宏类似的方式。尝试这样的事情:

/// <summary>
/// Calls a function's native implementation, then checks if the error code 
/// is not ErrorCode.Ok.  If it is, throws an AppException.
/// </summary>
/// <param name="nativeCall">
/// A function that returns the status code as an int.
/// </param>
private static void CheckErrorCode(Func<int> nativeCall)
{
    var returnCode = (ErrorCode)nativeCall();
    if(returnCode != ErrorCode.OK)
    {
        throw new AppException(returnCode);
    }
}

然后可以使用以下命令调用它:

public void getSize(out int sz)
{
    // drawback: compiler can't check that sz is always written.
    sz = 0;
    CheckErrorCode(() => ClibDllFunc3(datap, out sz));
}

lambda创建所谓的闭包这是一种使调用ClibDllFunc3(特定于此函数)的逻辑脱离处理其结果的逻辑(这是所有DLL函数的标准配置)的一种方法。与许多闭包不同,此闭包立即被调用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C#中简化的类似于C宏的函数调用

来自分类Dev

宏以简化目标C中的Singleton方法调用,以执行类似NSLocalizedString的操作

来自分类Dev

类似于 c# WPF 中的 keylistener

来自分类Dev

在目录中打开随机文件(在cmd中?)-类似于C ++还是类似于C#?

来自分类Dev

自己类的类似于C#数组的构造函数

来自分类Dev

C / C ++中的函数调用宏

来自分类Dev

Python中的方法/库,类似于C#中的NewtonSoft

来自分类Dev

NodeJS中的AES加密方法类似于C Sharp函数

来自分类Dev

F#函数中的类似于C ++的静态变量

来自分类Dev

C++ 中的函数类似于 numpy flatten

来自分类Dev

您如何在C语言中解释此类似于函数的宏`slice`的输出?

来自分类Dev

在C#中展开类似于Python的元组

来自分类Dev

类似于Java中C#的Process.Close事件?

来自分类Dev

C#结构上的复制构造函数,类似于C ++复制构造函数

来自分类Dev

转储类似于gcc的c结构,但作为可调用c函数

来自分类Dev

类似于定义为c#的摘要

来自分类Dev

Java SimpleDateFormat类似于C#

来自分类Dev

类似于C#的图形实现

来自分类Dev

“类型”的使用类似于变量(c#)

来自分类Dev

C#定义类似于PHP的数组

来自分类Dev

Java SimpleDateFormat类似于C#

来自分类Dev

函数的原型类似于在调用例程中声明函数?

来自分类Dev

类似于C ++中Android的ArrayMap的容器

来自分类Dev

以类似C的语法调用函数

来自分类Dev

是否有类似于c#上的Environment.TickCount的NodeJs类/函数?

来自分类Dev

C中是否有类似于C#的out / out关键字的内容?

来自分类Dev

C ++非虚函数的行为类似于虚函数

来自分类Dev

C ++中的Modulo函数,其行为类似于Matlab中的mod

来自分类Dev

正在传递地址,但是它的工作方式类似于在C中按值调用?

Related 相关文章

  1. 1

    C#中简化的类似于C宏的函数调用

  2. 2

    宏以简化目标C中的Singleton方法调用,以执行类似NSLocalizedString的操作

  3. 3

    类似于 c# WPF 中的 keylistener

  4. 4

    在目录中打开随机文件(在cmd中?)-类似于C ++还是类似于C#?

  5. 5

    自己类的类似于C#数组的构造函数

  6. 6

    C / C ++中的函数调用宏

  7. 7

    Python中的方法/库,类似于C#中的NewtonSoft

  8. 8

    NodeJS中的AES加密方法类似于C Sharp函数

  9. 9

    F#函数中的类似于C ++的静态变量

  10. 10

    C++ 中的函数类似于 numpy flatten

  11. 11

    您如何在C语言中解释此类似于函数的宏`slice`的输出?

  12. 12

    在C#中展开类似于Python的元组

  13. 13

    类似于Java中C#的Process.Close事件?

  14. 14

    C#结构上的复制构造函数,类似于C ++复制构造函数

  15. 15

    转储类似于gcc的c结构,但作为可调用c函数

  16. 16

    类似于定义为c#的摘要

  17. 17

    Java SimpleDateFormat类似于C#

  18. 18

    类似于C#的图形实现

  19. 19

    “类型”的使用类似于变量(c#)

  20. 20

    C#定义类似于PHP的数组

  21. 21

    Java SimpleDateFormat类似于C#

  22. 22

    函数的原型类似于在调用例程中声明函数?

  23. 23

    类似于C ++中Android的ArrayMap的容器

  24. 24

    以类似C的语法调用函数

  25. 25

    是否有类似于c#上的Environment.TickCount的NodeJs类/函数?

  26. 26

    C中是否有类似于C#的out / out关键字的内容?

  27. 27

    C ++非虚函数的行为类似于虚函数

  28. 28

    C ++中的Modulo函数,其行为类似于Matlab中的mod

  29. 29

    正在传递地址,但是它的工作方式类似于在C中按值调用?

热门标签

归档