【问题标题】:While accessing C++ function from C program, getting error message "Access violation reading location"从 C 程序访问 C++ 函数时,收到错误消息“访问冲突读取位置”
【发布时间】:2026-01-09 15:35:02
【问题描述】:

我正在尝试使用 Visual Studio 2012 IDE 从 C 程序访问 C++ 函数。当我调试时,我在 TestCpp.cpp 中收到以下错误,在 Method: helloworld() 中,在 Line: http_client cli( U("http://localhost:55505/api/Notification"));

MyTestCLib.exe 中 0x0000000076D23290 (ntdll.dll) 处未处理的异常:0xC0000005: 访问冲突读取位置0x00000621BC90B128。

请在下面找到代码sn-p。

MyTestCLib.c

#include <ctype.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <my_global.h>
#include <mysql.h>
#include <m_ctype.h>

#include "TestCpp.h"

int main()
{
    helloWorld();
    return 0;
}

TestCpp.h

#ifndef HEADER_FILE
 #define HEADER_FILE

 #ifdef __cplusplus
     extern "C" {
 #endif
         void helloWorld();
 #ifdef __cplusplus
     }
 #endif

 #endif

TestCpp.cpp

// 使用 C++ REST API SDK 从 C++ 调用 REST API

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include "TestCpp.h"

using namespace utility;                    // Common utilities like string conversions
using namespace web;                        // Common features like URIs.
using namespace web::http;                  // Common HTTP functionality
using namespace web::http::client;          // HTTP client features
using namespace concurrency::streams;       // Asynchronous streams
using namespace std;


void helloWorld()
{

        http_client cli( U("http://localhost:55505/api/Notification") );

        ostringstream_t uri;
        uri << U("/PostNotification");

        json::value bodyarray = json::value::array();

        json::value body = json::value::object();
        body[U("TicketNumber")] = json::value::string( U("25868") );
        body[U("NotificationMessage")] = json::value::string( U("Test Notification Message") );

        bodyarray[0] = body;

        http_response response = cli.request( methods::POST, uri.str(), bodyarray.serialize(), U("application/json") ).get();
        if ( response.status_code() == status_codes::OK &&
            response.headers().content_type() == U("application/json") )
        {
            json::value json_response = response.extract_json().get();
            ucout << json_response.serialize() << endl;
        }
        else
        {
            ucout << response.to_string() << endl;
            getchar();
        }
}

【问题讨论】:

  • 如果你从 cpp 主函数调用你的函数,你会得到同样的错误吗?如果它在该构造函数的第一行崩溃,则感觉它与 c/cpp 的事情根本无关。
  • 我可以从我的 cpp 主函数调用我的函数。当我将它作为单独的 cpp 程序运行时,它工作正常。但是当我从 C 调用它时,我得到了这个错误。
  • 奇怪,只是为了划掉列表,确保调用约定是相同的。 (例如_stdcall)在标头 decl 和实现 cpp 中。
  • 您可能希望在标头中将其声明为void HelloWorld(void);。空参数列表在 C 和 C++ 中的含义不同。
  • 是的,我试过 void HelloWorld(void);仍然给出同样的错误。调试时,控件进入 C++ 的 helloworld() 方法,并在第一行“http_client cli( U("localhost:55505/api/Notification"));”中给出错误。

标签: c++ c visual-studio-2010 visual-studio-2012


【解决方案1】:

从 MyTestCLib.c 你调用 helloWorld 声明为 C,但编译器只创建 C++ 函数版本。这个调用失败是因为 C++ 函数使用 CPU 注册表和堆栈不同的方式。有简单的解决方案。创建具有不同名称的 C 版本函数。

TestCpp.h

#ifdef __cplusplus
void helloWorld();
#else
void c_helloWorld();
#endif

TestCpp.cpp

#include "TestCpp.h"

void helloWorld(void) 
{ 
    /* cpp code */ 
}

extern "C" {
    void c_helloWorld(void)   // C version of helloWorld
    { 
        helloWorld();         // call cpp helloWorld
    }
}

扩展名为 .c 的源文件由 C 编译器编译。它不能调用 C++ 函数。但是在 C++ Compler 编译的 .cpp 文件中,您可以创建 C 函数。这个“C”函数(c_helloWorld)由 C++ 编译器编译,可以从 C-Complier 调用。也可以调用C++函数。

【讨论】: