Templates D模板请求

Templates D模板请求,templates,inline,d,Templates,Inline,D,我刚刚阅读了D编程语言中模板的全部文档,但似乎找不到一种方法来完成我非常简单的任务,对于函数,我需要在每个函数的开头插入3条汇编指令,我希望通过宏来自动执行,这样我就不必每次都手动编写 __gshared void jump() { asm{db START_KEY;} //bla bla bla asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;} } 像这样的东西应该被替换为 __gshared vo

我刚刚阅读了D编程语言中模板的全部文档,但似乎找不到一种方法来完成我非常简单的任务,对于函数,我需要在每个函数的开头插入3条汇编指令,我希望通过宏来自动执行,这样我就不必每次都手动编写

__gshared void jump()
{
    asm{db START_KEY;}

    //bla bla bla

    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}
像这样的东西应该被替换为

__gshared void jump()
{
    mixin starttemplate();

    //bla bla bla

    mixin endtemplate();
}
在C语言中,我会这样做

#define STARTASM() asm{.......}
template endtemplate()
{
    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}
但是如果我尝试这样的事情

#define STARTASM() asm{.......}
template endtemplate()
{
    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

它会抛出一个错误,告诉我必须在模板中声明一个变量(我不想这样做,因为这里绝对需要性能)。

模板混合只能包含声明()。如果要插入任意代码,则需要字符串混合:

enum startTemplate = "asm{...}";
enum endTemplate = "asm{...}";

__gshared void jump()
{
    mixin(startTemplate);
    ...etc...
    mixin(endTemplate);
}
您可以使用此机制插入可使用简单D函数()生成的自定义程序集:


将asm命令保存为字符串并使用mixin如何

immutable string ASM_START=q{
    asm{db START_KEY;}
}
immutable string ASM_END=q{
    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

__gshared void jump()
{
    mixin(ASM_START);
    //bla bla bla
    mixin(ASM_END);
}
另一个选项是使用混合创建整个函数,并将其签名和内容(=正文)作为参数传递:

string functionWithAsm(string signature,string content)(){
    return Format!(q{
        %s
        {
            asm{db START_KEY;}
            %s
            asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
        }
        },signature,content);
}

mixin(functionWithAsm!("__gshared void jump()",q{
            /*some actual code*/
            })());

这样做的RAII类还可以删除
开始/结束部分,并使其不易出错。@pmr它必须是一个结构(而不是类),因为RAII要工作,它需要在堆栈上。@pmr RAII必须做什么?我在这里看不到分配的任何资源-我所看到的只是将D函数装配到某个调用约定中的汇编代码。@IdanArye RAII不一定与资源分配有太多关系,正如R所代表的那样。任何时候,如果您有两个始终必须配对的操作,您都可以使用RAII。您声明了一个结构,它在构造时执行第一个操作,在销毁时执行第二个操作。一个典型的例子是互斥锁上的自动锁定。构造时,它锁定互斥体,当它被销毁(无论是异常还是正常退出作用域)时,互斥体被解锁。这里有一个必须配对的开始和结束操作,因此RAII。@Jonathan如果这是一个可以通过函数调用解决的问题,我不认为询问者会试图强制模板并将其混入。在我看来,他似乎在试图使D函数符合某种调用约定,这就是他需要使用汇编程序的原因。结构构造和销毁无法更改调用方函数的调用约定。。。