本文整理汇总了C++中enif_release_binary函数的典型用法代码示例。如果您正苦于以下问题:C++ enif_release_binary函数的具体用法?C++ enif_release_binary怎么用?C++ enif_release_binary使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了enif_release_binary函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: efile_get_cwd
posix_errno_t efile_get_cwd(ErlNifEnv *env, ERL_NIF_TERM *result) {
ErlNifBinary result_bin;
size_t bytes_copied;
if(!enif_alloc_binary(256, &result_bin)) {
return ENOMEM;
}
while(getcwd((char*)result_bin.data, result_bin.size) == NULL) {
posix_errno_t saved_errno = errno;
if(saved_errno != ERANGE) {
enif_release_binary(&result_bin);
return saved_errno;
} else {
if(!enif_realloc_binary(&result_bin, result_bin.size * 2)) {
enif_release_binary(&result_bin);
return ENOMEM;
}
}
}
/* getcwd(2) guarantees null-termination. */
bytes_copied = strlen((const char*)result_bin.data);
if(!enif_realloc_binary(&result_bin, bytes_copied)) {
enif_release_binary(&result_bin);
return ENOMEM;
}
(*result) = enif_make_binary(env, &result_bin);
return 0;
}
开发者ID:ebengt,项目名称:otp,代码行数:34,代码来源:unix_prim_file.c
示例2: efile_get_device_cwd
posix_errno_t efile_get_device_cwd(ErlNifEnv *env, int device_index, ERL_NIF_TERM *result) {
ErlNifBinary result_bin;
/* _wgetdcwd might crash the entire emulator on debug builds since the CRT
* invalid parameter handler asserts if passed a non-existent drive (Or
* simply one that has been unmounted), so we check it ourselves to avoid
* that. */
if(!is_valid_drive(device_index)) {
return EACCES;
}
if(!enif_alloc_binary(MAX_PATH * sizeof(WCHAR), &result_bin)) {
return ENOMEM;
}
if(_wgetdcwd(device_index, (WCHAR*)result_bin.data, MAX_PATH) == NULL) {
enif_release_binary(&result_bin);
return EACCES;
}
if(!normalize_path_result(&result_bin)) {
enif_release_binary(&result_bin);
return ENOMEM;
}
(*result) = enif_make_binary(env, &result_bin);
return 0;
}
开发者ID:HansN,项目名称:otp,代码行数:29,代码来源:win_prim_file.c
示例3: geef_index_get
ERL_NIF_TERM
geef_index_get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
unsigned int stage;
ErlNifBinary path;
geef_index *index;
const git_index_entry *entry;
if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index))
return enif_make_badarg(env);
if (!enif_get_uint(env, argv[2], &stage))
return enif_make_badarg(env);
if (!enif_inspect_iolist_as_binary(env, argv[1], &path))
return enif_make_badarg(env);
if (geef_terminate_binary(&path) < 0) {
enif_release_binary(&path);
return geef_oom(env);
}
entry = git_index_get_bypath(index->index, (char *) path.data, stage);
enif_release_binary(&path);
if (entry == NULL)
return geef_error(env);
return entry_to_term(env, entry);
}
开发者ID:CODECOMMUNITY,项目名称:geef,代码行数:29,代码来源:index.c
示例4: nif_read
static ERL_NIF_TERM
nif_read(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
SRLY_STATE *sp = NULL;
unsigned long len = 0;
ErlNifBinary buf = {0};
ssize_t bufsz = 0;
if (!enif_get_resource(env, argv[0], SRLY_STATE_RESOURCE, (void **)&sp))
return enif_make_badarg(env);
if (!enif_get_ulong(env, argv[1], &len))
return enif_make_badarg(env);
if (!enif_alloc_binary(len, &buf))
return error_tuple(env, ENOMEM);
if ( (bufsz = read(sp->fd, buf.data, buf.size)) < 0) {
int err = errno;
enif_release_binary(&buf);
return error_tuple(env, err);
}
if (bufsz < buf.size && !enif_realloc_binary(&buf, bufsz)) {
enif_release_binary(&buf);
return error_tuple(env, ENOMEM);
}
return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &buf));
}
开发者ID:jj1bdx,项目名称:srly,代码行数:32,代码来源:serctl.c
示例5: msg_to_binary
/*-----------------------------------------------------------------------------------------------------------------------*/
static ERL_NIF_TERM msg_to_binary(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[])
{
ERL_NIF_TERM parser_res;
ERL_NIF_TERM msg_res;
ParserRes* parser = NULL;
FIXMsg* msg = NULL;
ERL_NIF_TERM res = get_parser_msg(env, argv[0], &parser_res, &msg_res, &parser, &msg);
if (res != ok_atom)
{
return res;
}
int32_t delimiter = 0;
if (!enif_get_int(env, argv[1], &delimiter) || delimiter <= 0 || delimiter >= 255)
{
return make_error(env, FIX_FAILED, "Wrong delimiter.");
}
uint32_t reqBuffLen = DEF_BINARY_SIZE;
ErlNifBinary bin;
if (!enif_alloc_binary(reqBuffLen, &bin))
{
return make_error(env, FIX_FAILED, "Unable to allocate binary.");
}
FIXError* error = NULL;
pthread_rwlock_rdlock(&parser->lock);
if (FIX_FAILED == fix_msg_to_str(msg, (char)delimiter, (char*)bin.data, bin.size, &reqBuffLen, &error))
{
if (reqBuffLen > bin.size) // realloc needed
{
if (!enif_realloc_binary(&bin, reqBuffLen))
{
res = make_error(env, FIX_FAILED, "Unable to reallocate binary.");
}
if (FIX_FAILED == fix_msg_to_str(msg, (char)delimiter, (char*)bin.data, bin.size, &reqBuffLen, &error))
{
res = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error));
fix_error_free(error);
}
}
else
{
res = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error));
fix_error_free(error);
}
}
pthread_rwlock_unlock(&parser->lock);
if (res != ok_atom)
{
enif_release_binary(&bin);
return res;
}
if (bin.size > reqBuffLen)
{
enif_realloc_binary(&bin, reqBuffLen);
}
ERL_NIF_TERM bin_term = enif_make_binary(env, &bin);
enif_release_binary(&bin);
return enif_make_tuple2(env, ok_atom, bin_term);
}
开发者ID:dmitryme,项目名称:fix_engine,代码行数:59,代码来源:fix_parser_nifs.c
示例6: read_file
/** @brief Reads an entire file into \c result, stopping after \c size bytes or
* EOF. It will read until EOF if size is 0. */
static posix_errno_t read_file(efile_data_t *d, size_t size, ErlNifBinary *result) {
size_t initial_buffer_size;
ssize_t bytes_read;
if(size == 0) {
initial_buffer_size = 16 << 10;
} else {
initial_buffer_size = size;
}
if(!enif_alloc_binary(initial_buffer_size, result)) {
return ENOMEM;
}
bytes_read = 0;
for(;;) {
ssize_t block_bytes_read;
SysIOVec read_vec[1];
read_vec[0].iov_base = result->data + bytes_read;
read_vec[0].iov_len = result->size - bytes_read;
block_bytes_read = efile_readv(d, read_vec, 1);
if(block_bytes_read < 0) {
enif_release_binary(result);
return d->posix_errno;
}
bytes_read += block_bytes_read;
if(block_bytes_read < (result->size - bytes_read)) {
/* EOF */
break;
} else if(bytes_read == size) {
break;
}
if(!enif_realloc_binary(result, bytes_read * 2)) {
enif_release_binary(result);
return ENOMEM;
}
}
/* The file may have shrunk since we queried its size, so we have to do
* this even when the size is known. */
if(bytes_read < result->size && !enif_realloc_binary(result, bytes_read)) {
ERTS_INTERNAL_ERROR("Failed to shrink read_file result.");
}
return 0;
}
开发者ID:cypherfox,项目名称:otp,代码行数:55,代码来源:prim_file_nif.c
示例7: eval2
static ERL_NIF_TERM eval2(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary script_binary;
if (!enif_inspect_binary(env, argv[0], &script_binary)){
return enif_make_badarg(env);
}
if (!enif_is_list(env, argv[1])) {
enif_release_binary(&script_binary);
return enif_make_badarg(env);
}
mrb_state *mrb;
mrbc_context *cxt;
mrb = mrb_open();
if (mrb == NULL) {
return enif_make_atom(env, "error");
}
unsigned int mrb_argv_len;
enif_get_list_length(env, argv[1], &mrb_argv_len);
mrb_value mrb_argv = mrb_ary_new(mrb);
ERL_NIF_TERM cur;
for(cur = argv[1]; !enif_is_empty_list(env, cur); ) {
ERL_NIF_TERM head, tail;
enif_get_list_cell(env, cur, &head, &tail);
mrb_ary_push(mrb, mrb_argv, erl2mruby(env, mrb, head));
cur = tail;
}
mrb_define_global_const(mrb, "ARGV", mrb_argv);
char *script = malloc(script_binary.size+1);
strncpy(script, (const char *)script_binary.data, (int)script_binary.size);
script[script_binary.size] = '\0';
cxt = mrbc_context_new(mrb);
struct mrb_parser_state* st = mrb_parse_string(mrb, (const char *)script, cxt);
int n = mrb_generate_code(mrb, st);
mrb_pool_close(st->pool);
mrb_value result = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value());
ERL_NIF_TERM erl_result = mruby2erl(env, mrb, result);
free(script);
mrbc_context_free(mrb, cxt);
mrb_close(mrb);
enif_release_binary(&script_binary);
return erl_result;
}
开发者ID:mururu,项目名称:erlang-mruby,代码行数:51,代码来源:mruby.c
示例8: nif_recvfrom
/* 0: socket, 1: length, 2: flags, 3: struct sockaddr length */
static ERL_NIF_TERM
nif_recvfrom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
int sockfd = -1;
unsigned long len = 0;
unsigned long salen = 0;
int flags = 0;
ErlNifBinary buf = {0};
ErlNifBinary sa = {0};
ssize_t bufsz = 0;
if (!enif_get_int(env, argv[0], &sockfd))
return enif_make_badarg(env);
if (!enif_get_ulong(env, argv[1], &len))
return enif_make_badarg(env);
if (!enif_get_int(env, argv[2], &flags))
return enif_make_badarg(env);
if (!enif_get_ulong(env, argv[3], &salen))
return enif_make_badarg(env);
if (!enif_alloc_binary(len, &buf))
return error_tuple(env, ENOMEM);
if (!enif_alloc_binary(salen, &sa))
return error_tuple(env, ENOMEM);
if ( (bufsz = recvfrom(sockfd, buf.data, buf.size, flags,
(sa.size == 0 ? NULL : (struct sockaddr *)sa.data),
(socklen_t *)&salen)) == -1) {
enif_release_binary(&buf);
enif_release_binary(&sa);
switch (errno) {
case EAGAIN:
case EINTR:
return enif_make_tuple2(env, atom_error, atom_eagain);
default:
return error_tuple(env, errno);
}
}
PROCKET_REALLOC(buf, bufsz);
PROCKET_REALLOC(sa, salen);
return enif_make_tuple3(env, atom_ok, enif_make_binary(env, &buf),
enif_make_binary(env, &sa));
}
开发者ID:alepharchives,项目名称:procket,代码行数:49,代码来源:procket.c
示例9: spi_data_rw_nif
static ERL_NIF_TERM
spi_data_rw_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
int channel, len;
ErlNifBinary buf;
ERL_NIF_TERM atom_fail, err_code;
if (!enif_get_int(env, argv[0], &channel) ||
!enif_inspect_binary(env, argv[1], &buf) ||
!enif_get_int(env, argv[2], &len))
{
return enif_make_badarg(env);
}
enif_realloc_binary(&buf, len);
int result = wiringPiSPIDataRW(channel, buf.data, len);
if (result >= 0) {
return enif_make_tuple2(env,
atom_ok,
enif_make_binary(env, &buf));
} else {
atom_fail = enif_make_atom(env, "failed_to_read_write_data");
err_code = enif_make_int(env, result);
enif_release_binary(&buf);
return enif_make_tuple2(env,
atom_error,
enif_make_tuple2(env, atom_fail, err_code));
}
}
开发者ID:alepharchives,项目名称:wpi,代码行数:30,代码来源:wpi.c
示例10: nif_tcgetattr
static ERL_NIF_TERM
nif_tcgetattr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
SRLY_STATE *sp = NULL;
ErlNifBinary buf = {0};
int err = 0;
if (!enif_get_resource(env, argv[0], SRLY_STATE_RESOURCE, (void **)&sp))
return enif_make_badarg(env);
if (!enif_alloc_binary(sizeof(struct termios), &buf))
return error_tuple(env, ENOMEM);
if (tcgetattr(sp->fd, (struct termios *)buf.data) < 0) {
err = errno;
enif_release_binary(&buf);
return error_tuple(env, err);
}
return enif_make_tuple2(env,
atom_ok,
enif_make_binary(env, &buf));
}
开发者ID:jj1bdx,项目名称:srly,代码行数:25,代码来源:serctl.c
示例11: entry_to_term
ERL_NIF_TERM entry_to_term(ErlNifEnv *env, const git_index_entry *entry)
{
ErlNifBinary id, path;
size_t len;
if (geef_oid_bin(&id, &entry->id) < 0)
return geef_oom(env);
len = strlen(entry->path);
if (!enif_alloc_binary(len, &path)) {
enif_release_binary(&id);
return geef_oom(env);
}
memcpy(path.data, entry->path, len);
return enif_make_tuple(env, 13, atoms.ok,
enif_make_int64(env, entry->ctime.seconds),
enif_make_int64(env, entry->mtime.seconds),
enif_make_uint(env, entry->dev),
enif_make_uint(env, entry->ino),
enif_make_uint(env, entry->mode),
enif_make_uint(env, entry->uid),
enif_make_uint(env, entry->gid),
enif_make_int64(env, entry->file_size),
enif_make_binary(env, &id),
enif_make_uint(env, entry->flags),
enif_make_uint(env, entry->flags_extended),
enif_make_binary(env, &path));
}
开发者ID:CODECOMMUNITY,项目名称:geef,代码行数:29,代码来源:index.c
示例12: nif_read
/* 0: socket, 1: length */
static ERL_NIF_TERM
nif_read(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
int fd = -1;
unsigned long len = 0;
ErlNifBinary buf = {0};
ssize_t bufsz = 0;
if (!enif_get_int(env, argv[0], &fd))
return enif_make_badarg(env);
if (!enif_get_ulong(env, argv[1], &len))
return enif_make_badarg(env);
if (!enif_alloc_binary(len, &buf))
return error_tuple(env, ENOMEM);
if ( (bufsz = read(fd, buf.data, buf.size)) == -1) {
int err = errno;
enif_release_binary(&buf);
switch (err) {
case EAGAIN:
case EINTR:
return enif_make_tuple2(env, atom_error, atom_eagain);
default:
return error_tuple(env, err);
}
}
PROCKET_REALLOC(buf, bufsz);
return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &buf));
}
开发者ID:alepharchives,项目名称:procket,代码行数:35,代码来源:procket.c
示例13: do_to_title
inline void do_to_title(
ErlNifBinary in,
ErlNifBinary& out,
int32_t& ulen,
UBreakIterator* iter,
const char* locale,
UErrorCode& status)
{
status = U_ZERO_ERROR;
if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
ulen = u_strToTitle(
(UChar*) out.data, /* src */
ulen, /* len of src */
(UChar*) in.data,
TO_ULEN(in.size),
iter, /* Iterator */
locale,
&status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
/* enlarge buffer if it was too small */
enif_release_binary(&out);
return;
}
if (FROM_ULEN(ulen) != out.size) {
/* shrink binary if it was too large */
enif_realloc_binary(&out, FROM_ULEN(ulen));
}
}
开发者ID:alepharchives,项目名称:i18n,代码行数:33,代码来源:i18n_string.cpp
示例14: do_to_utf8
inline void do_to_utf8(
ErlNifBinary in,
ErlNifBinary& out,
int32_t& len,
UErrorCode& status)
{
status = U_ZERO_ERROR;
if (!enif_alloc_binary(len, &out)) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
u_strToUTF8(
(char*) out.data, /* dest */
len,
&len,
(const UChar*) in.data, /* src */
TO_ULEN(in.size), /* len of src */
&status);
if (U_FAILURE(status)) {
enif_release_binary(&out);
return;
}
if (len != (int32_t) out.size) {
/* shrink binary if it was too large */
enif_realloc_binary(&out, len);
}
}
开发者ID:alepharchives,项目名称:i18n,代码行数:30,代码来源:i18n_string.cpp
示例15: hexlify_nif
static ERL_NIF_TERM
hexlify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary bin, ret;
unsigned int flags = 0;
unsigned i, j;
const char* digits;
if (argc != 2 ||
!enif_inspect_binary(env, argv[0], &bin) ||
!enif_get_uint(env, argv[1], &flags)) {
return enif_make_badarg(env);
}
digits = (flags & HMAC_UPPER) ? UPPER : LOWER;
enif_alloc_binary(bin.size*2, &ret);
for (i = 0, j = 0; i < bin.size; ++i) {
unsigned char c = bin.data[i];
ret.data[j++] = digits[(c & 0xF0) >> 4];
ret.data[j++] = digits[(c & 0x0F)];
}
if (flags & HMAC_STRING) {
const char* data = (char*)ret.data;
ERL_NIF_TERM s = enif_make_string_len(env, data, ret.size, ERL_NIF_LATIN1);
enif_release_binary(&ret);
return s;
} else {
return enif_make_binary(env, &ret);
}
}
开发者ID:cclam0827,项目名称:erlsha2,代码行数:29,代码来源:hmac_nif.c
示例16: enc_destroy
void
enc_destroy(Encoder* e)
{
if(e->curr != NULL) {
enif_release_binary(e->curr);
}
}
开发者ID:Gustav-Simonsson,项目名称:jiffy,代码行数:7,代码来源:encoder.c
示例17: dh_compute_key_nif
ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */
BIGNUM *other_pub_key = NULL,
*dh_p = NULL,
*dh_g = NULL;
DH *dh_priv = DH_new();
/* Check the arguments and get
my private key (dh_priv),
the peer's public key (other_pub_key),
the parameters p & q
*/
{
BIGNUM *dummy_pub_key = NULL,
*priv_key = NULL;
ERL_NIF_TERM head, tail;
if (!get_bn_from_bin(env, argv[0], &other_pub_key)
|| !get_bn_from_bin(env, argv[1], &priv_key)
|| !enif_get_list_cell(env, argv[2], &head, &tail)
|| !get_bn_from_bin(env, head, &dh_p)
|| !enif_get_list_cell(env, tail, &head, &tail)
|| !get_bn_from_bin(env, head, &dh_g)
|| !enif_is_empty_list(env, tail)
/* Note: DH_set0_key() does not allow setting only the
* private key, although DH_compute_key() does not use the
* public key. Work around this limitation by setting
* the public key to a copy of the private key.
*/
|| !(dummy_pub_key = BN_dup(priv_key))
|| !DH_set0_key(dh_priv, dummy_pub_key, priv_key)
|| !DH_set0_pqg(dh_priv, dh_p, NULL, dh_g)
) {
if (dh_p) BN_free(dh_p);
if (dh_g) BN_free(dh_g);
if (other_pub_key) BN_free(other_pub_key);
if (dummy_pub_key) BN_free(dummy_pub_key);
if (priv_key) BN_free(priv_key);
return enif_make_badarg(env);
}
}
{
ErlNifBinary ret_bin;
int size;
enif_alloc_binary(DH_size(dh_priv), &ret_bin);
size = DH_compute_key(ret_bin.data, other_pub_key, dh_priv);
BN_free(other_pub_key);
DH_free(dh_priv);
if (size<=0) {
enif_release_binary(&ret_bin);
return atom_error;
}
if (size != ret_bin.size) enif_realloc_binary(&ret_bin, size);
return enif_make_binary(env, &ret_bin);
}
}
开发者ID:KennethL,项目名称:otp,代码行数:60,代码来源:dh.c
示例18: to_html_nif
static ERL_NIF_TERM to_html_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary markdown_binary;
ErlNifBinary output_binary;
char *html;
size_t html_len;
int options = 0;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_inspect_binary(env, argv[0], &markdown_binary)){
return enif_make_badarg(env);
}
if (markdown_binary.size <= 0){
const char *empty_string = "";
const int empty_len = strlen(empty_string);
enif_alloc_binary(empty_len, &output_binary);
strncpy((char*)output_binary.data, empty_string, empty_len);
return enif_make_binary(env, &output_binary);
}
html = cmark_markdown_to_html((const char *)markdown_binary.data, markdown_binary.size, options);
html_len = strlen(html);
enif_release_binary(&markdown_binary);
enif_alloc_binary(html_len, &output_binary);
strncpy((char*)output_binary.data, html, html_len);
return enif_make_binary(env, &output_binary);
};
开发者ID:jamesdphillips,项目名称:cmark.ex,代码行数:32,代码来源:cmark_nif.c
示例19: Sink
Sink(): used(0)
{
if (!enif_alloc_binary(0, &bin)) {
enif_release_binary(&bin);
THROW_EXC("enif_alloc_binary() failed");
}
}
开发者ID:fdmanana,项目名称:esnappy,代码行数:7,代码来源:esnappy_nif.cpp
示例20: eval1
static ERL_NIF_TERM eval1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary script_binary;
if (!enif_inspect_binary(env, argv[0], &script_binary)){
return enif_make_badarg(env);
}
mrb_state *mrb;
mrbc_context *cxt;
mrb = mrb_open();
if (mrb == NULL) {
return enif_make_atom(env, "error");
}
char *script = malloc(script_binary.size+1);
script[script_binary.size] = '\0';
strncpy(script, (const char *)script_binary.data, (int)script_binary.size);
ERL_NIF_TERM erl_result;
cxt = mrbc_context_new(mrb);
struct mrb_parser_state* st = mrb_parse_string(mrb, (const char *)script, cxt);
int n = mrb_generate_code(mrb, st);
mrb_pool_close(st->pool);
mrb_value result = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value());
erl_result = mruby2erl(env, mrb, result);
free(script);
mrbc_context_free(mrb, cxt);
mrb_close(mrb);
enif_release_binary(&script_binary);
return erl_result;
}
开发者ID:mururu,项目名称:erlang-mruby,代码行数:35,代码来源:mruby.c
注:本文中的enif_release_binary函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论