  | 
				Server Help Community forums for Subgame, ASSS, and bots   
				 | 
			 
		 
		 
                
                
                
       
	
	
		| Author | 
		Message | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 1:28 am     Post subject: C++ : Inheritance,Template and Threads problems | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				I have a class (Layer) from which another class (Layer_net) inherits. Other classes will inherit from it eventually.
 
I made the Layer class a template because there is a specific data type that I want to specify for each child class.
 
I'm having problems to define class functions outside the class body. They compile fine, but the linker freaks out when one of the function appears in the code.
 
 
	#define T_LAYER template <typename T>
 
 
T_LAYER
 
class Layer
 
{
 
public:
 
//stuff...
 
void Func1();
 
void Func2() { printf("hi, this is Func2\n"); }
 
};
 
 
T_LAYER
 
void Layer<T>::Func1()
 
{
 
   printf("hi, this is Func1\n");
 
}
 
 
 
 
 
//meanwhile, in another class not far away...
 
 
struct HeaderNetwork
 
{
 
   char ip[4];
 
};
 
 
class Layer_net : public Layer<HeaderNetwork>
 
{
 
public:
 
   //stuff
 
};
 
 
 
 
//and in the main...
 
 
int main(void)
 
{
 
   Layer_net net;
 
 
   net.Func1();
 
   net.Func2();
 
}
 
  |   
 
Ok, it seems the above code works if you put it all in the same file.
 
 
I then split it up in a header file and 2 cpp's like so:
 
 
header.h
 
	
 
#include <stdio.h>
 
#include <stdlib.h>
 
 
struct HeaderNetwork
 
{
 
   char ip[4];
 
};
 
 
 
template <typename T>
 
class Layer
 
{
 
public:
 
 
   //stuff...
 
   void Func1(int);
 
   void Func2() { printf("hi, this is Func2\n"); }
 
};
 
 
 
 
//meanwhile, in another class not far away...
 
 
class Layer_net : public Layer<HeaderNetwork>
 
{
 
public:
 
   //stuff
 
};
 
  |   
 
 
 
layer.cpp
 
	
 
#include <stdio.h>
 
#include <stdlib.h>
 
 
 
#include "header.h"
 
 
template <typename T>
 
void Layer<T>::Func1(int a)
 
{
 
   printf("hi, this is Func1\n");
 
}
 
  |   
 
 
main.cpp
 
	
 
#include "header.h"
 
 
//and in the main...
 
 
int main(void)
 
{
 
   Layer_net net;
 
 
   net.Func1(1);
 
   net.Func2();
 
 
   getchar();
 
}  |   
 
 
Build results:
 
1>------ Build started: Project: test, Configuration: Debug Win32 ------
 
1>Compiling...
 
1>main.cpp
 
1>Generating Code...
 
1>Compiling...
 
1>layer.cpp
 
1>Generating Code...
 
1>Linking...
 
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layer<struct HeaderNetwork>::Func1(int)" (?Func1@?$Layer@UHeaderNetwork@@@@QAEXH@Z) referenced in function _main
 
1>D:\Sam\Prog Projects\GPA785\trunk\Debug\test.exe : fatal error LNK1120: 1 unresolved externals
 
1>Build log was saved at "file://d:\Sam\Prog Projects\GPA785\trunk\test\Debug\BuildLog.htm"
 
1>test - 2 error(s), 0 warning(s)
 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 
 
 
Can anyone figure out what's happening?
 
Using Visual Studio 2005 _________________ (Insert a bunch of dead links here)
  Last edited by Samapico on Mon Sep 28, 2009 2:22 am, edited 1 time in total | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 2:00 am     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				I think I found my answer
 
 
http://cpp.developpez.com/faq/cpp/?page=templates#DIVERS_templates
 
(in french)
 
 
Basically, for some reason I have to make the layer.cpp NOT compile, and instead of including the header in it, I must include the cpp at the end of the header file...
 
 
 
I don't really understand why, but it works   | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 2:21 am     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				I have another somewhat related problem, and I'm pretty tired now, so excuse me if it's dumb:
 
 
 
Still in my template class, I got some function declared:
 
 
DWORD WINAPI threadloop(LPVOID iValue);
 
 
and defined later.
 
And then I want to create a thread in there...
 
 
First try:
 
	hthread = CreateThread(NULL, 0, threadloop, "", 0, &threadID);     |   error C3867: 'Layer<T>::threadloop': function call missing argument list; use '&Layer<T>::threadloop' to create a pointer to member
 
 
Ok... second try:
 
	hthread = CreateThread(NULL, 0, &Layer<T>::threadloop, "", 0, &threadID);     |   error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__stdcall Layer<T>::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE'
 
 
And then I desperately tried to typecast it:
 
	hthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(&Layer<T>::threadloop), "", 0, &threadID);  |   
 
 
It failed.
 
A lot of stuff in there looks weird to me, but I started from an example given by the teacher... but yeah, he wasn't using templates, obviously   | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Doc Flabby Server Help Squatter
  
   Joined: Feb 26 2006 Posts: 636 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 5:05 am     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				I recommend looking at pthreads    or using a C++ framework.  Working directly with the Windows API is a PITA but anyways:
 
 
	
 
hthread = CreateThread(NULL, 0, &Layer<T>::threadloop, "", 0, &threadID);
 
  |   
 
 
The problem here is the compiler does not know what T is.   Creating an instance of the class Layer<T> and pass it to the function might fix this problem.  
 
 
eg,
 
	
 
Layer<int> t = new Layer<int>;
 
hthread = CreateThread(NULL, 0, &t::threadloop, "", 0, &threadID);
 
  |   
 
 
This might not work btw  
 
 
I'm not overally familier with templates (i've not used them) in C++ but this link might help http://docs.google.com/gview?a=v&q=cache:twJe98TSVCIJ:www.allankelly.net/static/writing/overload/Threads/ThreadTemplate.pdf+templates+theading&hl=en&gl=uk&sig=AFQjCNEN1kd0XAxuQ2BA4Gq6xtyPrEfVsA[/code] _________________ Rediscover online gaming. Get Subspace | STF The future...prehaps | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		 | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Doc Flabby Server Help Squatter
  
   Joined: Feb 26 2006 Posts: 636 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 10:44 am     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				You would think it would, but it is C++ after all   
 
 
I found the source for that link which has threads created inside Templates (go to bottom of the page)  
 
 
http://www.allankelly.net/writing/softdesign.html
 
http://www.allankelly.net/static/writing/overload/Threads/threadssource.zip
 
 
From the source (snippit) you can see its a bit of a hack job    Essentially you have to pass the RunThread an object that implements a "run" function (this might sound familier  )
 
	
 
   void RunThread(   T      &x,
 
               long   stackSize = 0)
 
   {
 
      // each object represents one thread
 
      // therefore, should not launch multiple threads with one object
 
      assert (NULL == m_threadHandle);
 
 
      // other parameters may be dafaulted if needed
 
      DWORD dwStack = (DWORD) stackSize;
 
 
      // create a  thread
 
      m_threadHandle = CreateThread(  
 
                        NULL,         // pointer to thread security attributes  
 
                        dwStack,      // initial thread stack size, in bytes
 
                        StartRun,      // pointer to thread function  
 
                        &x,            // argument for new thread 
 
                        0,            // creation flags 
 
                        &m_threadId);   // pointer to returned thread identifier 
 
      DWORD last = GetLastError();   // useful for debug stepping
 
 
      if (NULL == m_threadHandle)
 
      {
 
         throw std::runtime_error("Failed to start thread");
 
      }
 
   }
 
 
static unsigned long __stdcall StartRun(void *param)
 
   {   
 
      T* object = static_cast<T*> (param);   // reclaim object type
 
      object->Run();
 
      return 0;
 
   }
 
  |  
  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 7:10 pm     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				hmmmm, but the argument of RunThread would still have to be of type Layer<T>, since I want the Run() function to be in there
 
 
Not sure how to translate this in my project... | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Dr Brain Flip-flopping like a wind surfer
  
  Age:39  Gender:  Joined: Dec 01 2002 Posts: 3502 Location: Hyperspace Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 7:32 pm     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				This is why C++ always seems horrible to me. Simple, easy things are complicated and non-intuitive. You use it if you have to, but stay away from it otherwise. _________________ Hyperspace Owner
 
 
Smong> so long as 99% deaths feel lame it will always be hyperspace to me | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		
			
			  
			    
				
					 Posted: Mon Sep 28, 2009 10:54 pm     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				| I could go the easy way and get rid of the template, that would just give me some copy paste to do | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Samapico No, these DO NOT look like penises, ok?
  
   Joined: May 08 2003 Posts: 1252 Offline
  | 
		
			
			  
			    
				
					 Posted: Thu Oct 01, 2009 11:57 am     Post subject:  | 
					  | 
					      | 
				 
			     
			   | 
			 
			
				
  | 
			 
			
				 	  | Samapico wrote: | 	 		  | I could go the easy way and get rid of the template, that would just give me some copy paste to do | 	  Oh well... I went the easy way  
 
I didn't actually need the members of the type in the base class, I only needed to know the sizeof it to allocate memory and such. So I just used an int for the size, and initialize it to sizeof(MyHeader) in the derived class.
 
 
F*** templates. | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	  
	    
	  
	   | 
	
	
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
  | 
   
 
  
Software by php BB © php BB Group Server Load: 490 page(s) served in previous 5 minutes. 
		 |