| Hello all,
I just finished implementing and testing plugin opcodes for Csound 4 on the
Legacy Mac platform. I built and tested the pans, metro, and testOpcode
libraries, all with success (a few changes were needed to compile testOpcode
"ANSI-strict", though).
I went the route of using dl_opcodes.c since this file was already being
used in the Mac build. I was not sure if load_opcodes.c was working yet,
but it should be pretty easy to convert my code over to use the API instead.
So, I am pretty excited about having this new functionality available for
the Mac!
:)
Code is below.
Anthony Kozar
anthony.kozar@utoledo.edu
/*
dl_opcodes.c:
Copyright (C) 2002 John ffitch
This file is part of Csound.
The Csound Library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Csound is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Csound; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#define BETA
#include "cs.h"
#ifdef LINUX
#include
#elif WIN32
#undef u_char
#undef u_short
#undef u_int
#undef u_long
#define PUBLIC __declspec(dllexport)
#define LIBRARY_CALL WINAPI
#include
#endif
int csoundLoadExternal(void)
{
return 0;
}
int csoundLoadExternals(void)
{
char *libname;
#ifdef LINUX
void *handle;
#elif WIN32
long handle;
#elif defined(mac_classic)
CFragConnectionID handle;
OSErr err;
Str63 macLibName;
Str255 errName;
Ptr mainAddr;
Ptr symAddr;
CFragSymbolClass symClass;
#else
void *handle = NULL;
#endif
char *error;
char buffer[256];
OENTRY *(*init)(GLOBALS*);
long (*size)(void);
if (cglob.oplibs==NULL) return 1;
printf("Loading libraries %s\n", cglob.oplibs);
strcpy(buffer, cglob.oplibs);
libname = strtok(buffer, ",");
#ifdef BETA
printf("libname %s\n", libname);
#endif
while (libname!=NULL) {
#ifdef LINUX
handle = dlopen (libname, RTLD_NOW | RTLD_GLOBAL);
#elif WIN32
handle = (long) LoadLibrary(libname);
#elif defined(mac_classic)
if (strlen(libname) < 64) {
strcpy((char*)macLibName, libname);
c2pstr((char*)macLibName);
}
else {
printf("%s is not a valid library name because it is too long.\n",
libname);
goto next;
}
err = GetSharedLibrary(macLibName, kPowerPCCFragArch, kLoadCFrag,
&handle, &mainAddr, errName);
if (err!=0) printf("Failed to load opcode library %s with Mac error
%d.\n", libname, err);
#endif
if (!handle) {
#ifdef LINUX
printf("Failed to load %s for %s.\n", libname, dlerror());
#elif WIN32
printf("Failed to load %s.\n", libname);
#endif
}
else {
OENTRY *opcodlst_n;
long length, olength;
#ifdef BETA
printf("Found handle\n");
#endif
#ifdef LINUX
size = dlsym(handle, "opcode_size");
if ((error = dlerror()) != NULL) {
printf("Failed to initialise %s: %s", libname, error);
goto next;
}
#ifdef BETA
printf("Found size\n");
#endif
length = (*size)();
#ifdef BETA
printf("Length=%d\n", length);
#endif
init = dlsym(handle, "opcode_init");
#ifdef BETA
printf("Found init\n");
#endif
if ((error = dlerror()) != NULL) {
printf("Failed to initialise %s: %s", libname, error);
goto next;
}
#ifdef BETA
printf("Calling init\n");
#endif
opcodlst_n = (*init)(&cglob);
olength = oplstend-opcodlst;
/* end LINUX */
#elif WIN32
size = (long(*)(void))GetProcAddress((HINSTANCE)handle,
"opcode_size");
if (size == NULL) {
printf("Failed to initialise %s", libname);
goto next;
}
#ifdef BETA
printf("Found size\n");
#endif
length = (*size)();
#ifdef BETA
printf("Length=%d\n", length);
#endif
init = (OENTRY *(*)(GLOBALS*))GetProcAddress((HINSTANCE)handle,
"opcode_init");
#ifdef BETA
printf("Found init\n");
#endif
if (init == NULL) {
printf("Failed to initialise %s", libname);
goto next;
}
#ifdef BETA
printf("Calling init\n");
#endif
opcodlst_n = (*init)(&cglob);
olength = oplstend-opcodlst;
/* end WIN32 */
#elif defined(mac_classic)
err = FindSymbol(handle, "\popcode_size", &symAddr, &symClass);
if (err!=0) {
printf("Failed to initialise %s with Mac error %d.\n", libname,
err);
goto next;
}
else if (symClass == kDataCFragSymbol) {
printf("Failed to initialise %s because opcode_size it not a code
symbol.\n", libname);
goto next;
}
size = (long (*)(void))symAddr;
#ifdef BETA
printf("Found size\n");
#endif
length = (*size)();
#ifdef BETA
printf("Length=%d\n", length);
#endif
err = FindSymbol(handle, "\popcode_init", &symAddr, &symClass);
if (err!=0) {
printf("Failed to initialise %s with Mac error %d.\n", libname,
err);
goto next;
}
else if (symClass == kDataCFragSymbol) {
printf("Failed to initialise %s because opcode_init it not a code
symbol.\n", libname);
goto next;
}
init = (OENTRY *(*)(GLOBALS*))symAddr;
#ifdef BETA
printf("Found init\n");
printf("Calling init\n");
#endif
opcodlst_n = (*init)(&cglob);
olength = oplstend-opcodlst;
#endif /* mac_classic */
#ifdef BETA
printf("Got opcodlst %p\noplstend=%p, opcodlst=%p, length=%d\n",
opcodlst_n, oplstend, opcodlst, olength);
printf("Adding %d(%d) -- first opcode is %s\n",
length, length/sizeof(OENTRY), opcodlst_n[0].opname);
#endif
opcodlst = (OENTRY*) mrealloc(opcodlst, olength*sizeof(OENTRY) +
length);
memcpy(opcodlst+olength, opcodlst_n, length);
oplstend = opcodlst + olength + length/sizeof(OENTRY);
}
next:
libname = strtok(NULL, ",");
}
#ifdef BETA
printf("All loaded\n");
#endif
return 1;
} |