简体   繁体   中英

SWIG + CMAKE: init function missing

I was provided with a CMAKE-File for a c++ Code and want to wrap its function into python. Whenever I try to import the function it's giving me an Import Error:

dynamic module does not define init function (init_main)

This is the c++ code:

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <Memory/Interface.hpp>
#include <Memory/Subscription.hpp>

using namespace memory::interface;
using namespace memory;

MemoryPtr mMem;
Subscription *s;

std::string write_document;







void subscriber_callback(const Event &event) {

  std::cout << "Received an event:" << std::endl;
  switch (event.getType()) {

        case Event::INSERT:
                std::cout << "Insert event with document ID = " << event.getID() << std::endl;
                break;

        case Event::REMOVE:
                std::cout << "Remove event with document ID = " << event.getID() << std::endl;
                break;

        case Event::QUERY:
                std::cout << "Query event with document ID = " << event.getID() << std::endl;
                break;

        case Event::REPLACE:
                std::cout << "Replace event with document ID = " << event.getID() << std::endl;
                break;

        case Event::ALL:
                std::cout << "Generic event with document ID = " << event.getID() << std::endl;
                break;

        default: std::cout << "Unknown event type." << std::endl;
  }
  std::cout << "Contained document is: " << event.getDocument() << std::endl;

}



extern "C" int main(int argc, char *argv[]) {
  // validate app arguments
  if(argc < 3) {
    std::cerr << "Usage  : " << argv[0] << " <xcf:ShortTerm> <XPATH-trigger>" << std::endl;
    return 1;
  }
  try {
    // instantiate the memory interface
    mMem = MemoryInterface::getInstance(argv[1]);
    std::cout << "Memory interface initialized" << std::endl;

    // create the trigger
    std::string xpath(argv[2]);

    // create a subscriber to a specific xpath event
    s = new Subscription(
      Condition(Event::INSERT, xpath),
      TriggeredAction(boost::bind(&subscriber_callback, _1))
      );
    mMem->subscribe (*s);
    std::cout << "Memory interface subscriber initialized" << std::endl;

    // insert command/text to memory
    write_document = "<command><stop /></command>";
    mMem->insert(write_document);
    std::cout << "Written to Memory interface" << std::endl;

    // wait for key press
    std::string end;
    std::cin >> end;
  }
  catch (const MemoryInterfaceException& e) {
    std::cerr << "MemoryInterfaceException: " << e.what() << std::endl;
    return 1;
  }
  catch(std::exception &e) {
    std::cerr << std::endl << "Could not initialize memory::interface. Reason:"
    << std::endl << e.what() << std::endl;
    return 1;
  }
  return 0;
}

This is the CMAKE File to which I added the last SWIG part:

cmake_minimum_required(VERSION 3.0.2)
project(xcf_minimal_readwrite)

find_package(PkgConfig)

IF(PKG_CONFIG_FOUND)
  message(STATUS "found pkgconfig")

  SET(MODULE "Memory")

  IF(Memory_FIND_REQUIRED)
    SET(Memory_REQUIRED "REQUIRED")
  ENDIF()
  PKG_CHECK_MODULES(Memory ${Memory_REQUIRED} ${MODULE})

  FIND_LIBRARY(Memory_LIBRARY
    NAMES ${Memory_LIBRARIES}
    HINTS ${Memory_LIBRARY_DIRS}
  )
  SET(Memory_LIBRARIES ${Memory_LIBRARY})


  SET(MODULE "xmltio")

  IF(xmltio_FIND_REQUIRED)
    SET(xmltio_REQUIRED "REQUIRED")
  ENDIF()
  PKG_CHECK_MODULES(xmltio ${xmltio_REQUIRED} ${MODULE})

  FIND_LIBRARY(xmltio_LIBRARY
    NAMES ${xmltio_LIBRARIES}
    HINTS ${xmltio_LIBRARY_DIRS}
  )
  SET(xmltio_LIBRARIES ${xmltio_LIBRARY})


ENDIF()

IF(Memory_FOUND)
  message(STATUS "found Memory")
  include_directories(${Memory_INCLUDE_DIRS} ${xmltio_INCLUDE_DIRS})

  add_executable(${PROJECT_NAME} main.cc)
  target_link_libraries(${PROJECT_NAME} ${Memory_LIBRARIES} ${xmltio_LIBRARIES})


  install(TARGETS ${PROJECT_NAME}
    RUNTIME DESTINATION bin)


ENDIF()




# This is the part for Python SWIG:

FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})

FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})

SET(CMAKE_SWIG_FLAGS "")

SET_SOURCE_FILES_PROPERTIES(main.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(main.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(main python main.i main.cc) 
SWIG_LINK_LIBRARIES(main ${Memory_LIBRARIES} ${xmltio_LIBRARIES} ${PYTHON_LIBRARIES})

And this is how my main.i looks like:

/* File : main.i */
%module main
%{
/* Put headers and other declarations here */
extern int main(int argc, char *argv[]);
%}


extern int main(int argc, char *argv[]);

Any clue what went wrong here?

Is "main" maybe a bad name for this?

The swig invocation generates a source file that defines the init_main function. This file is either not compiled, or its object file is not linked into the shared object that constitutes your python extension.

Yes, main is a bad name, but here you are stuck at an earlier stage than where this might become a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM