Import problem
BlitzMax Forums/BlitzMax Programming/Import problem
| ||
Hi, I have a bunch of functions that I want to define in my application, but a few types that I want to hold separate in imported files. I tried using "Extern" to define the functions inside the imported files, but then I get "duplicate identifier". Is there any way to have some functions from an imported file point to functions defined in the main file? |
| ||
If i understood you right, you might need a third file, like: MyFunctions.bmx: Function MyFunction() .. End Function MyTypes.bmx: Type myType .. End Type myFunction() 'imported through root source file MyRootSourceFile.bmx: Import "MyFunctions.bmx" Import "MyTypes.bmx" Hope thats it. |
| ||
Sadly, that won't work because of the way "Import" works. MyTypes.bmx should be able to be compiled by itself. However, it is not aware of the functions in Myfunctions.bmx. That's where I thought declaring them with Extern...EndExtern would solve the problem. But honestly, I have no idea how extern should work... I though it would solve the problem. |
| ||
So in a nutshell your trying to have nested calling functions... AppLevel.bmx Level1.bmx Level2.bmx The problems you can run into here are cyclic dependencies where a function or type will appear more than once in the source tree. Two techniques that can get around this that I know of... 1. Use a core import/include file to bring everthing together where needed e.g. at the app level. 2. Turn the more generic code into a module (will also reduce compile time) 3. 1 and 2 are not mutually exclusive. Hope that helps! |
| ||
Ok, let me try to explain this better: I've got one type that is generic, but it needs some stuff: Type MyGenericType Method Draw() Plot oX(), oY() EndMethod EndType Those oX and oY functions are dependant on certain things in my application, so they're not generic. I want to use "Import" to get this type inside the application, but I can't because the functions are not defined for the .bmx file (they are defined outside): Import "MyGenericType.bmx" Function oX#() Return 10.3 EndFunction Function oY#() Return 15.1 EndFunction I've tried using extern to define them and got myself a nice bunch of errors that the functions are duplicate (those errors happened when I was actually defining them. I suppose the errors come from the fact that they were already defined by "Extern"... but isn't "Extern" supposed to work just INSIDE that file? SO that if I import the file they're still undefined? |
| ||
A Generic type using non-generic functionality? There appears to be a minor flaw in your design somewhere, I would say... btw, Extern is for C/C++ style linking, so that's not likely to work in a hurry. Why can't you just do something based on what Arowx/Merx ( :-p ) suggests : main.bmx Import "common_stuff.bmx" ' this is actually not required because of the following import... Import "mytype.bmx" ' use some common stuff here mytype.bmx Import "common_stuff.bmx" ' use some common stuff in the type common_stuff.bmx ' define some common stuff here ? |
| ||
Hmm... I'll try that... I mean generic as in "almost generic" :) |
| ||
Thats either a semantic bug or a realy tricky problem. Have you already tried: MyTypes: Extern "MyFunctions.bmx" Function MyFunction() End Extern Type MyType() Method RunExternFunctionality() MyFunction() End Method End Type MyFunctions: Extern "MyTypes.bmx" Type MyType End Extern Function MyFunction() .. End Function I'm sure you can EXTERN types! Dunno if that kinda 'nested' Externing works. If you need to import the bmx files before (not having to do so is my last remaining hope)- i've no ideas left :~ |
| ||
If only your functions were in another one but the root source file! |
| ||
You might be able to use function pointers.Type MyGenericType Field __fOX() Field __fOX() Method Draw() Plot __fOX(), __fOY() EndMethod EndType Import "MyGenericType.bmx" MyGenericTypeInstance.__fOX = oX MyGenericTypeInstance.__fOY = oY Function oX() print "the battle ox had mighty horns" return 1 EndFunction Function oY() print "oy, ship ahead!" return 231 EndFunction |
| ||
So you have an object that depends on other specific objects.. that's not so unusual but there are several ways of avoiding issues of cyclic dependency. My favourite way of dealing with these situations is to make your base objects dependant on an interface. They exist in their own little world 'connected' to the outside world via an interface. The object is a toaster, the interface is the toasters plug, and the rest of your code is your house where you want the toaster to work. The toaster will never know about your house, in fact the same toaster is sold all over the world with different plugs. Function pointers would work, but you may end up with a lot of them. Defining an abstract type that clearly lays out what your base type needs and expects from the outside world makes it easy to maintain. Here's a base type with an interface that has some abstract methods; That code will compile fine on it's own. So to use foo.. If your base type is very simple (not worth interfacing) you could make the abstract functions part of foo itself, then define an application specific foo that fills in the gaps. An interface is really useful when it can serve many types and/or functions. |