我正在使用marmalade中间件软件编写一个带有c ++的移动应用程序,我的插件我有一个依赖于已编译的python库的组件。
我的应用程序适用于此2.6版本: https://github.com/marmalade/python
使用套接字支持切换到2.7: https://github.com/guyburton/python-loves-marmalade
我的第一步是为正确的平台编译我的库,然后将其链接到我的应用程序>这会创建一个文件libpython.a(debug libpython_d.a)
我的应用程序有一些c-python函数,所以我还链接了所需的python.h和pyrun.h头文件。
我的标题都没有引用python.h或python.c而且wmApplication.cpp根本没有引用python,它确实调用了我的插件。
1> ARM Compiling(GCC) c:\marmalade\7.3\web\wmapplication\wmApplication.cpp ...
1> ARM Compiling(GCC) c:\TestMove\fluidSec\pyRun.cpp ...
1> ARM Linking(GCC) ...
1> c:/TestMove/python-master/lib/arm\libpython.a(python.obj): In function `main':
1> python.c:(.text.startup.main+0x0): multiple definition of `main'
1> :Release_fluidSec_vc12x_gcc_arm/wmApplication.obj(wmApplication.cpp) : first defined here (col (.text.startup.main+0x0))
当我在python版本2.6上时,我的插件工作了然后我切换到了python 2.7的不同实现
难道不是'吨 " 'main'的多重定义"当你有两个具有相同功能签名的主要功能时,只会出现问题???意味着他们都有相同的程序结构?据我所知,无论实际的函数名是main,都会发生这种情况,编译器会将其作为编译时将其切换为main。
我没有任何其他python.c实例(我搜索过)
另外:如果我使用库的调试版本编译,错误似乎保留了构建库的旧路径(在网络驱动器Z:..即使我断开连接后),如果我打开库在十六进制编辑器中,路径嵌入在调试信息中......任何更改都可能是个问题吗?
1> ARM Compiling(GCC) c:\marmalade\7.3\web\wmapplication\wmApplication.cpp ...
1> ARM Compiling(GCC) c:\TestMove\fluidSec\pyRun.cpp ...
1> ARM Linking(GCC) ...
1> c:/TestMove/python-master/lib/arm\libpython_d.a(python.obj): In function `main':
1> z:/_ProjectFolder/python-master/modified/Modules/python.c:11: multiple definition of `main'
1> :Debug_fluidSec_vc12x_gcc_arm/wmApplication.obj(wmApplication.cpp) : first defined here (col (.text.main+0x0))
有什么想法吗?我显然遗漏了一些东西! (肯定清理了所有临时文件夹并重新启动,希望缓存问题)
这里是python.c
/* Minimal main program -- everything is loaded from the library */
#include "Python.h"
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif
int
main(int argc, char **argv)
{
/* 754 requires that FP exceptions run in "no stop" mode by default,
* and until C vendors implement C99's ways to control FP exceptions,
* Python requires non-stop mode. Alas, some platforms enable FP
* exceptions by default. Here we disable them.
*/
#ifdef __FreeBSD__
fp_except_t m;
m = fpgetmask();
fpsetmask(m & ~FP_X_OFL);
#endif
return Py_Main(argc, argv);
}
wmApplication.c
/*
* (C) 2001-2012 Marmalade. All Rights Reserved.
*
* This document is protected by copyright, and contains information
* proprietary to Marmalade.
*
* This file consists of source code released by Marmalade under
* the terms of the accompanying End User License Agreement (EULA).
* Please do not use this program/source code before you have read the
* EULA and have agreed to be bound by its terms.
*/
#include <string>
#include "s3eKeyboard.h"
#include "s3eConfig.h"
#include "s3eWebView.h"
#include "IwDebug.h"
#include "IwGx.h"
#include "../IwWMDispatcher.h"
#include "FallbackPage.h"
#include "../IwWMRegisterModules.h"
#define WEB_DEFAULT_ROOT_DIRECTORY "webassets"
#define WEB_DEFAULT_URL "index.html"
//TOOD Wide char support (relevant for the next line)??
#define ALLOCATION_SIZE_FOR_CONFIG_STRINGS sizeof(char) * S3E_CONFIG_STRING_MAX
#define WEB_DEFAULT_SCHEME LOCAL_ROM_URL
#define URL_HAS_SCHEME(x) strstr(x, "://")
typedef enum CurrentURLType
{
STARTUP_URL_USER_DEFINED,
STARTUP_URL_DEFAULT,
STARTUP_URL_EMBEDDED
} CurrentURLType;
//TODO Implement these globals in a better way (there's no point yet as we may wildly change
//where all out defaults are coming from)
// Tells us which url to try and navigate to (no ownership)
static const char* const * g_WebStartupURL = NULL;
// Scheme to locate local files (might one day not be const)
static const char* const g_LocalFileURLScheme = WEB_DEFAULT_SCHEME;
// Root folder of all web app assets
static char* g_WebAssetsRootDirectory = NULL;
// User defined start URL from icf
static char* g_WebUserDefinedURL = NULL;
// Default start URL if user didn't specify one
static char* g_WebDefaultURL = NULL;
// State representing which stage of fallbacks we're in
static CurrentURLType g_CurrentURLType = STARTUP_URL_USER_DEFINED;
// Name of temp file to create and load as our final fallback url
static const char* g_WebInternalFallbackURL = LOCAL_RAM_URL "error.html";
// Flag to indicate whether we need to cleanup a tempfile
static bool g_DeleteTempURL = false;
static bool g_UsingWinSim = false;
// The main webview
static s3eWebView* g_WebView = NULL;
// The Javascript Dispatcher
static IwWebMarmalade::CDispatcher* g_Dispatcher = NULL;
// Fwd delcarations
bool CreateFallbackPage(const char* url, const char* content);
void DeleteFallbackPage(const char* url);
//Assumes that str is long enough to take the prefix
static void strprepend(const char* prefix, char* str)
{
const int originalLen = strlen(str);
const int prefixLen = strlen(prefix);
//Shift the string along
memmove(str+prefixLen, str, originalLen);
//Can use memcpy for the prefix
memcpy(str, prefix, prefixLen);
//NULL terminate
str[originalLen+prefixLen] = '\0';
}
static bool InitGlobals()
{
if (!g_WebAssetsRootDirectory)
{
if (!(g_WebAssetsRootDirectory = (char*)s3eMalloc(ALLOCATION_SIZE_FOR_CONFIG_STRINGS + 1))) // + 1 for possible extra "/"
return false; //Like it's going to happen at this stage!
if (s3eConfigGetString("Web", "WebRootDirectory", g_WebAssetsRootDirectory) != S3E_RESULT_SUCCESS)
{
strcpy(g_WebAssetsRootDirectory, WEB_DEFAULT_ROOT_DIRECTORY);
}
int length = strlen(g_WebAssetsRootDirectory);
if (g_WebAssetsRootDirectory[length - 1] != '/' || g_WebAssetsRootDirectory[length - 1] != '\\') //TODO Better way?
{
g_WebAssetsRootDirectory[length] = '/';
g_WebAssetsRootDirectory[length + 1] = 0;
}
//Root directory mustn't contain a scheme
if (URL_HAS_SCHEME(g_WebAssetsRootDirectory))
{
IwTrace(WEBMARMALADE, ("WebRootDirectory must not contain a scheme"));
return false;
}
}
if (!g_WebUserDefinedURL)
{
const int totalCapacity = ALLOCATION_SIZE_FOR_CONFIG_STRINGS +
strlen(g_WebAssetsRootDirectory) + strlen(g_LocalFileURLScheme);
if (!(g_WebUserDefinedURL = (char*)s3eMalloc(totalCapacity)))
return false; //Like it's going to happen at this stage!
if (s3eConfigGetString("Web", "WebStartURL", g_WebUserDefinedURL) != S3E_RESULT_SUCCESS)
{
//No user defined URL
g_CurrentURLType = STARTUP_URL_DEFAULT;
g_WebUserDefinedURL[0] = 0;
}
//TODO This means if the user specifies e.g. www.madewithmarmalade.com then this fails.
//We should possibly check for things like "www." as well.
else if (!URL_HAS_SCHEME(g_WebUserDefinedURL))
{
//The user defined url is "relative" then add the scheme and the default file location
strprepend(g_WebAssetsRootDirectory, g_WebUserDefinedURL);
strprepend(g_LocalFileURLScheme, g_WebUserDefinedURL);
}
}
if (!g_WebDefaultURL)
{
const int totalCapacity = strlen(WEB_DEFAULT_URL) +
strlen(g_WebAssetsRootDirectory) + strlen(g_LocalFileURLScheme);
if (!(g_WebDefaultURL = (char*)s3eMalloc(totalCapacity)))
return false; //Like it's going to happen at this stage!
strcpy(g_WebDefaultURL, WEB_DEFAULT_URL);
if (!URL_HAS_SCHEME(g_WebDefaultURL))
{
//The default url is "relative" then add the scheme and the default file location
strprepend(g_WebAssetsRootDirectory, g_WebDefaultURL);
strprepend(g_LocalFileURLScheme, g_WebDefaultURL);
}
}
if (g_CurrentURLType == STARTUP_URL_USER_DEFINED)
g_WebStartupURL = &g_WebUserDefinedURL;
else if (g_CurrentURLType == STARTUP_URL_DEFAULT)
g_WebStartupURL = &g_WebDefaultURL;
g_UsingWinSim = s3eDeviceGetInt(S3E_DEVICE_OS) == S3E_OS_ID_WINDOWS;
IwTrace(WMAPP, ("xxxxxxxxxxxxxxxxxxxxxx: (userdefined) %s", g_WebUserDefinedURL));
return true;
}
static bool CheckQuit()
{
bool rtn = s3eDeviceCheckQuitRequest()
|| (s3eKeyboardGetState(s3eKeyEsc) & S3E_KEY_STATE_PRESSED)
|| (s3eKeyboardGetState(s3eKeyAbsBSK) & S3E_KEY_STATE_PRESSED);
if (rtn)
IwTrace(WEBMARMALADE, ("Quitting Web Marmalade App"));
return rtn;
}
static int32 handleReset(void* systemData, void* userData)
{
s3eWebViewNavigate(g_WebView, *g_WebStartupURL);
return 1;
}
static void Terminate()
{
s3eDeviceUnRegister(S3E_DEVICE_SIMULATOR_RESTART, handleReset);
if (g_Dispatcher)
{
delete g_Dispatcher;
g_Dispatcher = NULL;
}
if (g_WebView)
{
s3eWebViewDestroy(g_WebView);
g_WebView = NULL;
//Free the strings
free(g_WebAssetsRootDirectory);
free(g_WebDefaultURL);
free(g_WebUserDefinedURL);
g_WebAssetsRootDirectory = NULL;
g_WebDefaultURL = NULL;
g_WebUserDefinedURL = NULL;
if (g_DeleteTempURL)
DeleteFallbackPage(g_WebInternalFallbackURL);
}
}
void DoNavigate()
{
IwTrace(WEBMARMALADE, ("loading url = %s", *g_WebStartupURL));
s3eWebViewNavigate(g_WebView, *g_WebStartupURL);
}
static int32 screenResizePending(void* systemData, void* userData)
{
IwTrace(WEBMARMALADE, ("screenResize Pending, calling s3eSurfaceShow()"));
// First call to surface show resizes the surface and calls the S3E_SURFACE_SCREENSIZE
// callback. No surface is actually displayed
s3eSurfaceShow();
// On ios the first call only sets the state to resize pending. The second call actually performs it
s3eSurfaceShow();
return 0;
}
static int32 screenSizeChanged(void* systemData, void* userData)
{
IwTrace(WEBMARMALADE, ("screenSizeChanged callback fired. Resizing webview"));
s3eWebViewResize(g_WebView, 0, 0, s3eSurfaceGetInt(S3E_SURFACE_WIDTH), s3eSurfaceGetInt(S3E_SURFACE_HEIGHT));
// This is annoying. If we don't do this on android then the OS locks the surface and
// we the screen doesn't even rotate natively.
s3eSurfaceShow();
return 0;
}
static int32 pageNotFound(s3eWebView *instance, void *systemData, void *userData)
{
switch (g_CurrentURLType)
{
case STARTUP_URL_USER_DEFINED:
g_CurrentURLType = STARTUP_URL_DEFAULT;
IwTrace(WEBMARMALADE, ("pageNotFound: trying default url = %s", g_WebDefaultURL));
g_WebStartupURL = &g_WebDefaultURL;
break;
case STARTUP_URL_DEFAULT:
g_CurrentURLType = STARTUP_URL_EMBEDDED;
IwTrace(WEBMARMALADE, ("pageNotFound: creating and loading fallback url = %s", g_WebInternalFallbackURL));
if (!(g_DeleteTempURL = CreateFallbackPage(g_WebInternalFallbackURL, g_WebInteralFallbackContent)))
{
IwTrace(WEBMARMALADE, ("failed to create fallback url: quitting"));
s3eDeviceRequestQuit();
return 0;
}
else
{
g_WebStartupURL = &g_WebInternalFallbackURL;
}
break;
default:
IwTrace(WEBMARMALADE, ("pageNotFound: can't find loadable page, quitting"));
s3eDeviceRequestQuit();
return 0;
}
DoNavigate();
return 0;
}
bool Init()
{
// Clear the debug screen from behind the app (you can see it on iOS when you drag
// the browser).
s3eSurfaceClear(0, 0, 0);
s3eSurfaceShow();
if (!s3eWebViewAvailable())
{
IwError(("Webview not available"));
return false;
}
InitGlobals();
if (!(g_WebView = s3eWebViewCreate()))
{
IwTrace(WEBMARMALADE, ("Failed to create webview"));
return false;
}
g_Dispatcher = new IwWebMarmalade::CDispatcher(g_WebView);
if (!g_Dispatcher)
{
IwTrace(WEBMARMALADE, ("Failed to create dispatcher"));
return false;
}
s3eWebViewRegister(S3E_WEBVIEW_FAILED_LOADING, pageNotFound, 0, g_WebView);
s3eSurfaceRegister(S3E_SURFACE_SCREENSIZE, screenSizeChanged, NULL);
s3eDeviceRegister(S3E_DEVICE_SIMULATOR_RESTART, handleReset, NULL);
s3eSurfaceRegister((s3eSurfaceCallback)2, screenResizePending, NULL);
s3eWebViewShow(g_WebView, 0, 0, s3eSurfaceGetInt(S3E_SURFACE_WIDTH), s3eSurfaceGetInt(S3E_SURFACE_HEIGHT));
// For some iOS devices we need to call this on init otherwise the webview is not displayed
s3eSurfaceShow();
DoNavigate();
return true;
}
bool Update()
{
// Work-around since socket events do not unyield the app in windows
if (!g_UsingWinSim)
s3eDeviceYieldUntilEvent();
else
s3eDeviceYield(0);
s3eKeyboardUpdate();
return true;
}
int main()
{
IwTrace(WEBMARMALADE, ("Started Web Marmalade App"));
if (!Init())
return 0;
//Main loop
while (!CheckQuit())
{
if (!Update())
break;
}
Terminate();
return 0;
}
答案 0 :(得分:0)
我弄清楚为什么它以前工作过,现在它不是, 橘子酱MKB文件(设置可视化工作室进行交叉编译)在其中引用了python.c,以便在没有必要时包括它。
对于那些想要做同样的事情,在web橘子酱中使用python,我将在github上链接我的框架,因为我已经对python实现进行了大量更改,只是一些小问题(这让我感到困惑)方式太久无法解决)