0

I'm writing a mobile app with c++ using marmalade middleware software, my plugin I'm making has a component that relies on a compiled python library.

my application works with this 2.6 version: https://github.com/marmalade/python

switched to 2.7 with socket support: https://github.com/guyburton/python-loves-marmalade

My first step is I compile my library for the right platform, it is then linked into my application> this creates a file libpython.a ( debug libpython_d.a )

My application has some c-python functions so I also link the required python.h and pyrun.h headers.

none of my headers make reference to python.h or python.c And wmApplication.cpp doesnt make reference to python at all, it does call my plugin though.

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))

I had my plugin working when I was on python version 2.6 then I switched to a different implementation of python 2.7

Isn't " multiple definition of `main' "only an issue when you have two main functions with the same function signature??? meaning they both have the same program structure? As I understand this can happen regardless of the actual function name being main, the compiler switches it to main as compile time.

I don't have any other instances of python.c ( I searched )


Also: if i compile with the debug version of the library, the error appears to keep the old path in which the library was built ( on a network drive Z:.. even after I disconnect ), if I open the library in a hex editor the path is embedded in the debug info... any change this could be an issue?

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))

Any ideas? I'm clearly missing something! ( definitely cleaned all temp folders and restarted, hoping for a cache issue )


edit:

here is 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;
}
Community
  • 1
  • 1
flow
  • 571
  • 1
  • 4
  • 16

1 Answers1

0

I figured out why it was working before and now it wasn't, The marmalade MKB file ( which sets up visual studio for cross compiling) had python.c referenced in it to include when it wasn't necessary.

for those wanting to do the same, python in web marmalade, i'll be linking my framework on github as i've made numerous changes to the python implementations, just a few minor issues ( that took me way too long to solve)

flow
  • 571
  • 1
  • 4
  • 16