GVKun编程网logo

winapi – Unix中的全局命名事件(unix命名规则)

13

以上就是给各位分享winapi–Unix中的全局命名事件,其中也会对unix命名规则进行解释,同时本文还将给你拓展asp.net-web-api–OWIN中间件中的全局异常处理、c–ADL是否适用于全

以上就是给各位分享winapi – Unix中的全局命名事件,其中也会对unix命名规则进行解释,同时本文还将给你拓展asp.net-web-api – OWIN中间件中的全局异常处理、c – ADL是否适用于全局命名空间?、c – 为什么gcc会隐藏全局命名空间中的重载函数?、c – 为什么全局命名空间中的sort函数?等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

winapi – Unix中的全局命名事件(unix命名规则)

winapi – Unix中的全局命名事件(unix命名规则)

什么是Unix中的全局命名事件对象?我需要在unix中创建一个类似事件的命名对象,以便另一个进程可以设置它

Win32中的伪代码:

HANDLE hEvent=CreateEvent(...,"Global\\CSAPP");
while(1)
{
    WaitForSingleObject(hEvent);
    ...
}

在另一个过程中:

HANDLE hEvent=OpenEvent(...,"Global\\CSAPP");
SetEvent(hEvent);

解决方法

你可能正在寻找 named semaphore.

int initial = 0;
sem_t *sem = sem_open("/global_name",O_CREAT,0644,initial);

/* Down ("Wait"). */
sem_wait(sem);

/* Up ("Set") . */
sem_post(sem);

asp.net-web-api – OWIN中间件中的全局异常处理

asp.net-web-api – OWIN中间件中的全局异常处理

我正在ASP.NET Web API 2.1项目中创建一个统一的错误处理/报告,该项目构建在OWIN中间件(IIS HOST使用Owin.Host.SystemWeb)之上。
目前,我使用了一个自定义的异常记录器,它继承自System.Web.Http.ExceptionHandling.ExceptionLogger,并使用NLog将所有异常作为下面的代码记录:
public class NLogExceptionLogger : ExceptionLogger
{

    private static readonly Logger Nlog = LogManager.GetCurrentClassLogger();
    public override void Log(ExceptionLoggerContext context)
    {
       //Log using NLog
    } 
}

我想将所有API异常的响应体更改为友好的统一响应,它将使用System.Web.Http.ExceptionHandling.ExceptionHandler隐藏所有异常详细信息作为以下代码:

public class ContentNegotiatedExceptionHandler : ExceptionHandler
{
    public override void Handle(ExceptionHandlerContext context)
    {
        var errorDataModel = new ErrorDataModel
        {
            Message = "Internal server error occurred,error has been reported!",Details = context.Exception.Message,ErrorReference = context.Exception.Data["ErrorReference"] != null ? context.Exception.Data["ErrorReference"].ToString() : string.Empty,DateTime = DateTime.UtcNow
        };

        var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,errorDataModel);
        context.Result = new ResponseMessageResult(response);
    }
}

当异常发生时,这将返回以下客户端的响应:

{
  "Message": "Internal server error occurred,"Details": "Ooops!","ErrorReference": "56627a45d23732d2","DateTime": "2015-12-27T09:42:40.2982314Z"
}

现在,如果在Api Controller请求管道中发生任何异常,这一切都会很好。

但是在我的情况下,我正在使用中间件Microsoft.Owin.Security.OAuth来生成承载令牌,而这个中间件并不知道有关Web API异常处理的任何内容,所以例如如果异常已经被抛出在ValidateClientAuthentication方法中NLogExceptionLogger没有ContentNegotiatedExceptionHandler将知道有关此异常的任何操作,也不会尝试处理它,AuthorizationServerProvider中使用的示例代码如下所示:

public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        //Expcetion occurred here
        int x = int.Parse("");

        context.Validated();
        return Task.Fromresult<object>(null);
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        if (context.UserName != context.Password)
        {
            context.SetError("invalid_credentials","The user name or password is incorrect.");
            return;
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);

        identity.AddClaim(new Claim(ClaimTypes.Name,context.UserName));

        context.Validated(identity);
    }
}

所以我会感谢执行下面2个问题的任何指导:

1 – 创建一个全局异常处理程序,仅处理由OWIN中间商产生的异常?我跟着this answer,创建了一个异常处理目的的中间件,并将其注册为第一个,并且我能够执行源自“OAuthAuthorizationServerProvider”的日志异常,但是我不知道这是否是最佳的方法。

2 – 现在当我在上一步中实现日志记录时,我真的不知道如何更改异常的响应,因为在“OAuthAuthorizationServerProvider”中发生异常时,我需要向客户端返回一个标准的JSON模型。有一个相关的answer here我试图依赖,但它没有工作。

这是我的启动类和我为异常捕获/记录创建的自定义GlobalExceptionMiddleware。失踪的和平正在为任何异常返回统一的JSON响应。任何想法将不胜感激。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var httpConfig = new HttpConfiguration();

        httpConfig.MapHttpAttributeRoutes();

        httpConfig.Services.Replace(typeof(IExceptionHandler),new ContentNegotiatedExceptionHandler());

        httpConfig.Services.Add(typeof(IExceptionLogger),new NLogExceptionLogger());

        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,TokenEndpointPath = new PathString("/token"),AccesstokenExpireTimeSpan = TimeSpan.FromDays(1),Provider = new AuthorizationServerProvider()
        };

        app.Use<GlobalExceptionMiddleware>();

        app.USEOAuthAuthorizationServer(OAuthServerOptions);
        app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationoptions());

        app.UseWebApi(httpConfig);
    }
}

public class GlobalExceptionMiddleware : OwinMiddleware
{
    public GlobalExceptionMiddleware(OwinMiddleware next)
        : base(next)
    { }

    public override async Task Invoke(IOwinContext context)
    {
        try
        {
            await Next.Invoke(context);
        }
        catch (Exception ex)
        {
            NLogLogger.LogError(ex,context);
        }
    }
}

解决方法

好的,所以这比预期更容易,谢谢@Khalid的头脑,我最终创建了一个名为OwinExceptionHandlerMiddleware的Owin中间件,专门用于处理任何Owin中间件中发生的任何异常(记录它并在返回之前操纵响应)给客户)。

您需要将这个中间件注册为Startup类中的第一个,如下所示:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var httpConfig = new HttpConfiguration();

        httpConfig.MapHttpAttributeRoutes();

        httpConfig.Services.Replace(typeof(IExceptionHandler),Provider = new AuthorizationServerProvider()
        };

        //Should be the first handler to handle any exception happening in OWIN middlewares
        app.USEOwinExceptionHandler();

        // Token Generation
        app.USEOAuthAuthorizationServer(OAuthServerOptions);

        app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationoptions());

        app.UseWebApi(httpConfig);
    }
}

而在OwinExceptionHandlerMiddleware中使用的代码如下所示:

using AppFunc = Func<IDictionary<string,object>,Task>;

public class OwinExceptionHandlerMiddleware
{
    private readonly AppFunc _next;

    public OwinExceptionHandlerMiddleware(AppFunc next)
    {
        if (next == null)
        {
            throw new ArgumentNullException("next");
        }

        _next = next;
    }

    public async Task Invoke(IDictionary<string,object> environment)
    {
        try
        {
            await _next(environment);
        }
        catch (Exception ex)
        {
            try
            {

                var owinContext = new OwinContext(environment);

                NLogLogger.LogError(ex,owinContext);

                HandleException(ex,owinContext);

                return;
            }
            catch (Exception)
            {
                // If there's a Exception while generating the error page,re-throw the original exception.
            }
            throw;
        }
    }
    private void HandleException(Exception ex,IOwinContext context)
    {
        var request = context.Request;

        //Build a model to represet the error for the client
        var errorDataModel = NLogLogger.BuildErrorDataModel(ex);

        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        context.Response.ReasonPhrase = "Internal Server Error";
        context.Response.ContentType = "application/json";
        context.Response.Write(JsonConvert.SerializeObject(errorDataModel));

    }

}

public static class OwinExceptionHandlerMiddlewareAppBuilderExtensions
{
    public static void USEOwinExceptionHandler(this IAppBuilder app)
    {
        app.Use<OwinExceptionHandlerMiddleware>();
    }
}

c – ADL是否适用于全局命名空间?

c – ADL是否适用于全局命名空间?

Examples such as启用std类型的输出解释了 ADL如何用于“注入”某个函数/运算符,具体取决于应用fn / op的类型.

我想知道ADL完全适用于全局命名空间,也就是说,在global namespace scope声明(或通过使用可用)的类型是否使ADL在全局命名空间中寻找匹配函数?

具体来说,这些是等价的. ADL?:

// 1 - at global namespace scope
struct GlobalType {};

template< class Ch,class Tr>
std::basic_ostream<Ch,Tr>& operator<<(std::basic_ostream<Ch,Tr>& os,GlobalType const& x)
{
    os << ...;
    return os;
} 

// 2 - within namespace
namespace ecaps {

    struct EcapsType {};

    template< class Ch,class Tr>
    std::basic_ostream<Ch,EcapsType const& x)
    {
        os << ...;
        return os;
    } 

}

// 3 - Type brought to global NS via using,function at global scope
namespace other {
    struct OtherType {};    
}

using other::OtherType;

template< class Ch,OtherType const& x)
{
    os << ...;
    return os;
}

WRT.全局命名空间范围不需要ADL :(在现在删除的答案后更新)

一个Daniel Krügler of Committee fame describes an ADL problem如此:

This unqualified call has the effect that unqualified name lookup
happens and as a consequence of this,the compiler searches for the
name operator<<. beginning from the lexical location where the
operator<< call is found “upwards”
(…) starting in the current namespace and all the
namespaces that include that namespace (including the global
namespace,btw.) and – …

EMPH.矿.请注意外部名称空间的描述如何仅被视为“……来自词汇位置……”.他继续:

… and – as a second route – it performs a second phase of this
lookup the compiler searches in the so-called associated namespaces of
the argument types occurring in this call.

In the presented example,the first phase of the search fails,because
at the point where #include <iterator> exists,there is no
corresponding operator<< for these argument types in any namespace.
Note that your declaration of operator<< is provided lexically after
the point where the call of operator<< happens somewhere in some of
the library headers. The second phase of the search would also
consider locations that
follow the actual function call
,but only within the associated namespaces.

大胆的恩赐.矿.因此,在我看来,ADL适用于全局命名空间是相关的.当然,我很容易误解一些事情.

注意:这可能是标准的一种情况,只是没有明确地以某种方式提及它,因为全局NS就像任何其他命名空间一样 – 然后它可能不会,我对标准的了解非常有限.

解决方法

完全忘记我最初的答案,这是完全错误的.

根据C 11标准,关于ADL的§3.4.2(强调我的):

When the postfix-expression in a function call (5.2.2) is an
unqualified-id,other namespaces not considered during the usual
unqualified lookup
(3.4.1) may be searched,and in those namespaces,
namespace-scope friend function declarations (11.3) not otherwise
visible may be found.

简而言之,由于非限定查找将始终在全局命名空间中进行搜索,因此ADL将永远不会应用于全局命名空间.

c – 为什么gcc会隐藏全局命名空间中的重载函数?

c – 为什么gcc会隐藏全局命名空间中的重载函数?

void f() {}

namespace test
{
void f(int) {}    
void g() { f(); } // error in gcc 6.2.0
}

int main()
{
    test::g();
}

用g -std = c 1z main.cpp编译它,输出如下:

06001

我的编译器是gcc 6.2.0.

为什么gcc会隐藏全局命名空间中的重载函数?这符合C标准吗?

解决方法

Why does gcc hide overloaded functions in the global namespace? Is this conforming to the C++ standards?

是.简而言之,您不能通过不同的范围重载功能.据的unqualified name lookup的规则,对于克()f()的的调用,该名称可以˚F命名空间内测试中找到,则该名称查找停止; overload resolution之后(基于找到的名称)发生.这意味着全局命名空间中的f()根本不会被考虑,即使它看起来更合适.

(强调我的)

For an unqualified name,that is a name that does not appear to the
right of a scope resolution operator ::,name lookup examines the
scopes as described below,until it finds at least one declaration
of any kind,at which time the lookup stops and no further scopes are
examined.

In order to compile a function call,the compiler must first perform
name lookup,which,for functions,may involve argument-dependent
lookup,and for function templates may be followed by template
argument deduction. If these steps produce more than one candidate
function,then overload resolution is performed to select the function
that will actually be called.

您可以使用using将名称引入同一范围,即使它们成为实际的重载函数.

namespace test
{
    using ::f;        // introduce the name from global namespace
    void f(int) {}    
    void g() { f(); } // fine
}

c – 为什么全局命名空间中的sort函数?

c – 为什么全局命名空间中的sort函数?

为什么C中的全局命名空间中有一个排序函数?为什么这段代码会编译?

#include <iostream>
#include <vector>

int main() {
    std::vector<int> array(10);
    sort(array.begin(),array.end());
}

PS:clang –std = c 11 –stdlib = libc ./test.cpp

解决方法

sort不在全局命名空间中,它在std中.但是,vector :: begin()的结果类型也可以是std(这是依赖于实现的).如果是这样,则ADL(参数依赖查找)找到std :: sort.

如果您不希望ADL找到std :: sort,那么您可以进行限定调用而不是非限定的调用::: sort(array.begin(),array.end()).

今天关于winapi – Unix中的全局命名事件unix命名规则的介绍到此结束,谢谢您的阅读,有关asp.net-web-api – OWIN中间件中的全局异常处理、c – ADL是否适用于全局命名空间?、c – 为什么gcc会隐藏全局命名空间中的重载函数?、c – 为什么全局命名空间中的sort函数?等更多相关知识的信息可以在本站进行查询。

本文标签: