[疑难] 请问D能不能写 apache/php/等程序的module?

sofire 2007-08-03
请问现在可以用D语言写这些module吗?应该怎么做?

另外有个疑问,因为D现成的库很少,只好去调用C的库。
那是不是 理论上所有的C写的程序库,都可以用D来调用?
C++的库是不是就很难重用了?

谢谢!
tomqyp 2007-08-04
只知道fastcgi有个D版本的.做web开发的话可以试试
qiezi 2007-08-04
只要是有通用的初始化、结束函数,或者是使用动态加载的链接库,都可以用D来写,在合适的地方把GC给初始化就行了。

C库大部分可以在转换头文件后用在D里面,C++就很难说,二进制是可以兼容的,由于C++编译器的名称打乱方式也各不相同,加上有重载机制,可能工作量比较大。D里面保留了extern(C++),也可能在以后实现,但兼容多种编译器还是大问题。通过虚表兼容相对容易,COM就是这种方式,D也是支持的。
sofire 2007-08-05
请问 是不是只需要转换 C语言 被“直接”使用到的函数,数据结构就可以了;间接使用到的函数,数据结果可以不需要用extern在D语言中申明?我测试是可以的。

另外 extern(C): 这个语法到底是啥意思呢?文档上说的是:
affects all declarations until the next }
我的理解是影响到下一个extern申明为止,但好像不是这样。
试了几次,发现理解得总是不对。
好像它是影响到文档结束,用在 C 转换到D 的程序中不错。

谢谢
qiezi 2007-08-05
是的,只需要把你要用到的函数导出来就行了,它只需要这个符号而已。

extern(C):是到下一个为止,如果文档中只有他一个,当然就到结束了,注意行内的extern是暂时性的,你可以把每个声明影响到的部分用大括号包起来加深理解。比如:
extern(C):
void fun1();

extern(Windows) void fun2();

void fun3();

可以理解为:
extern(C){
  void fun1();
  extern(Windows) {
    void fun2();
  }
  void fun3();
}

很容易分辨出是在哪个声明范围内。
sofire 2007-08-05
我想用expat库解析xml,遇到一个不会的地方。

C程序定义了一个:
typedef void (*XML_StartElementHandler)(void *userData,
                    XML_Char *name,
                    XML_Char **atts);
typedef void (*XML_EndElementHandler)(void *userData,
                      const XML_Char *name);
void XML_SetElementHandler(XML_Parser parser,
              XML_StartElementHandler start,
              XML_EndElementHandler end);

在D语言中应该怎么处理 XML_StartElementHandler 和 XML_EndElementHandler 呢?

谢谢
oldrev 2007-08-05
sofire 写道
我想用expat库解析xml,遇到一个不会的地方。

C程序定义了一个:
typedef void (*XML_StartElementHandler)(void *userData,
                    XML_Char *name,
                    XML_Char **atts);
typedef void (*XML_EndElementHandler)(void *userData,
                      const XML_Char *name);
void XML_SetElementHandler(XML_Parser parser,
              XML_StartElementHandler start,
              XML_EndElementHandler end);

在D语言中应该怎么处理 XML_StartElementHandler 和 XML_EndElementHandler 呢?

谢谢

去掉 const,把 typedef 改为 alias
sofire 2007-08-05
我用htod,它翻译成了:
alias void function(void *userData, XML_Char *name, XML_Char **atts) XML_StartElementHandler;
alias void function(void *userData, XML_Char *name) XML_EndElementHandler;
sofire 2007-08-05
我写了一天的程序,想尽办法也不知道该怎么弄了。请:)

引用

import std.stdio;
import std.stream;

void startElement1(void* userData, XML_Char* name, XML_Char** atts)
{
    int i;
    int *depthPtr = cast(int *) userData;

    writefln("startE");

    // depthPtr 不正确
    *depthPtr = 1;

    for (i = 0; i < *depthPtr; i++)
        putchar('\t');

    writef(name);
    *depthPtr += 1;
}

void endElement1(void *userData, XML_Char *name)
{
    int *depthPtr = cast(int*) userData;
    *depthPtr -= 1;
    writefln("endE");
}

int main()
{
    int done;
    int depth = 0;
    XML_Parser parser;

    string fn = "a.xml";
    File f = new File(fn);

    XML_StartElementHandler startElement = cast(XML_StartElementHandler) &startElement1;
    XML_EndElementHandler endElement = cast(XML_EndElementHandler) &endElement1;

    parser  = XML_ParserCreate(null);
    XML_SetUserData(parser, &depth);
    XML_SetElementHandler(parser, startElement, endElement);

    while (!f.eof())
    {
        string line = f.readLine();
        //writefln(line, line.length);

        if (!XML_Parse(parser, cast(char*) line, line.length, done))
        {
            fprintf(stderr,
            "%s at line %d\n",
            XML_ErrorString(XML_GetErrorCode(parser)),
            XML_GetCurrentLineNumber(parser));
            return 1;
        }
    }

    XML_ParserFree(parser);
    return 0;
}

extern(C):

alias void* XML_Parser;
alias wchar XML_Char;
alias wchar XML_LChar;

XML_Parser XML_ParserCreate(XML_Char* encoding);
void XML_SetUserData(XML_Parser parser, void* userData);
void XML_SetElementHandler(XML_Parser parser,
      XML_StartElementHandler start,
      XML_EndElementHandler end);
int XML_Parse(XML_Parser parser, char *s, int len, int isFinal);
XML_LChar *XML_ErrorString(int code);
int XML_GetCurrentLineNumber(XML_Parser parser);
void XML_ParserFree(XML_Parser parser);

alias void function(void *userData, XML_Char *name, XML_Char **atts) XML_StartElementHandler;
alias void function(void *userData, XML_Char *name) XML_EndElementHandler;

enum XML_Error
{
    XML_ERROR_NONE,
    XML_ERROR_NO_MEMORY,
    XML_ERROR_SYNTAX,
    XML_ERROR_NO_ELEMENTS,
    XML_ERROR_INVALID_TOKEN,
    XML_ERROR_UNCLOSED_TOKEN,
    XML_ERROR_PARTIAL_CHAR,
    XML_ERROR_TAG_MISMATCH,
    XML_ERROR_DUPLICATE_ATTRIBUTE,
    XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
    XML_ERROR_PARAM_ENTITY_REF,
    XML_ERROR_UNDEFINED_ENTITY,
    XML_ERROR_RECURSIVE_ENTITY_REF,
    XML_ERROR_ASYNC_ENTITY,
    XML_ERROR_BAD_CHAR_REF,
    XML_ERROR_BINARY_ENTITY_REF,
    XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
    XML_ERROR_MISPLACED_XML_PI,
    XML_ERROR_UNKNOWN_ENCODING,
    XML_ERROR_INCORRECT_ENCODING,
    XML_ERROR_UNCLOSED_CDATA_SECTION,
    XML_ERROR_EXTERNAL_ENTITY_HANDLING,
    XML_ERROR_NOT_STANDALONE,
}

XML_Error XML_GetErrorCode(XML_Parser parser);



程序不能正确执行。
不知道是 parser  = XML_ParserCreate(null); 还是其他地方的问题。

对应的C程序:
引用

#include <stdio.h>
#include "xmlparse.h"

void startElement(void *userData, const char *name, const char **atts)
{
  int i;
  int *depthPtr = userData;
  for (i = 0; i < *depthPtr; i++)
    putchar('\t');
  puts(name);
  *depthPtr += 1;
}

void endElement(void *userData, const char *name)
{
  int *depthPtr = userData;
  *depthPtr -= 1;
}

int main()
{
  char buf[BUFSIZ];
  XML_Parser parser = XML_ParserCreate(NULL);
  int done;
  int depth = 0;
  XML_SetUserData(parser, &depth);
  XML_SetElementHandler(parser, startElement, endElement);

  FILE *fp = fopen("a.xml", "r");
  while (!feof(fp))
  {
    size_t len = fread(buf, 1, sizeof(buf), fp);
    done = len < sizeof(buf);
    if (!XML_Parse(parser, buf, len, done)) {
      fprintf(stderr,
      "%s at line %d\n",
      XML_ErrorString(XML_GetErrorCode(parser)),
      XML_GetCurrentLineNumber(parser));
      return 1;
    }
  }
  XML_ParserFree(parser);
  return 0;
}


这个是expat1.x中的例子,下载地址是:ftp://ftp.jclark.com/pub/xml/expat.zip


PS:
本来打算用它来解析RSS,弄了一天,还没有开始本来要做的事情。真郁闷。
sofire 2007-08-06
看了libeventd的实现,总算解决了。
void startElement1(void* userData, XML_Char* name,
XML_Char** atts)
{

要写成:
extern(C)
void startElement1(void* userData, XML_Char* name, XML_Char** atts)
{

打印 writef(name); 要写成
printf("%.*s", name);
Global site tag (gtag.js) - Google Analytics