mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-06 23:02:28 +01:00
Author:halw
Date:2008-10-02T21:44:24.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@68 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
[[Property:title|EiffelThread Tutorial]]
|
||||
[[Property:weight|-1]]
|
||||
[[Property:uuid|c1965bc3-23cf-25d6-02c1-717b7035d41c]]
|
||||
== EiffelThread Library Tutorial==
|
||||
Multithreaded applications provide a flexible, exciting way of utilizing the power of modern computer systems. EiffelThread supports a powerful multithreaded model, fast and easy to use.
|
||||
|
||||
The EiffelThread library is mapped to the native thread library of your platform such as Windows, POSIX, Solaris and Unix International Threads.
|
||||
|
||||
This document will explain how to use the EiffelThread library. To fully take advantage of this documentation you should know some basics about multithreaded systems
|
||||
|
||||
To enable multithreading in the EiffelStudio environment, you will need to do some changes in your project settings.
|
||||
|
||||
There are special considerations for using "once" features in an Eiffel multithreaded environment.
|
||||
|
||||
If you encounter problems, take a look at the FAQ list.
|
||||
|
||||
Users of the EiffelThread library in version 4.5 and older should read "changes between 4.5 and 5.0" to get the info they need to migrate their code to the new implementation of threads in Eiffel.
|
||||
|
||||
|
||||
@@ -27,7 +27,11 @@ Your thread is represented by a class which inherits from <eiffel>THREAD</eiffel
|
||||
|
||||
end -- class MY_THREAD
|
||||
</code>
|
||||
|
||||
|
||||
Creating a thread is like creating an Eiffel object:
|
||||
|
||||
|
||||
<code>
|
||||
my_thread: MY_THREAD
|
||||
-- MY_THREAD inherits from THREAD and defines
|
||||
@@ -36,16 +40,31 @@ Creating a thread is like creating an Eiffel object:
|
||||
create my_thread
|
||||
</code>
|
||||
|
||||
|
||||
{{note|You have created a thread object but have not started the thread itself yet. <br/>
|
||||
To run the thread, use the feature <eiffel>launch</eiffel> from <eiffel>THREAD</eiffel>. }}
|
||||
|
||||
|
||||
<code> my_thread.launch</code>
|
||||
|
||||
|
||||
On the Eiffel side, the procedure <eiffel>execute</eiffel> will be launched. This procedures deferred in class <eiffel>THREAD</eiffel>, you have to define it in <eiffel>MY_THREAD</eiffel>.
|
||||
|
||||
|
||||
On the C side, a C thread will be created and launched.
|
||||
{{warning| '''Caution''': you may call <eiffel>join_all</eiffel> and the end of the execution of the parent thread if you do not want it to die before its child, otherwise they may prematurely terminate. }}
|
||||
|
||||
|
||||
{{caution|You may call <eiffel>join_all</eiffel> and the end of the execution of the parent thread if you do not want it to die before its child, otherwise they may prematurely terminate. }}
|
||||
|
||||
|
||||
==The class MUTEX==
|
||||
|
||||
The implementation of the class <eiffel>MUTEX</eiffel> is mapped on the C standard thread library. An instance of class <eiffel>MUTEX</eiffel> can be shared between different thread.
|
||||
|
||||
|
||||
<eiffel>my_mutex.pointer</eiffel> is the pointer to the nested C mutex of <eiffel>my_mutex</eiffel>.
|
||||
|
||||
|
||||
* Declaration of the mutex:
|
||||
<code> my_mutex: MUTEX</code>
|
||||
|
||||
@@ -59,7 +78,7 @@ The implementation of the class <eiffel>MUTEX</eiffel> is mapped on the C standa
|
||||
<code> my_mutex.unlock</code>
|
||||
|
||||
* <eiffel>try_lock</eiffel>: if it is not locked yet, lock the mutex and return True, otherwise it returns False.
|
||||
<code> my_mutex.lock</code>
|
||||
<code> my_mutex.try_lock</code>
|
||||
|
||||
* Is my mutex initialized?
|
||||
<code> my_mutex.is_set</code>
|
||||
@@ -67,11 +86,15 @@ The implementation of the class <eiffel>MUTEX</eiffel> is mapped on the C standa
|
||||
|
||||
{{note|on Windows: The <eiffel>MUTEX</eiffel> objects on Windows are recursive while they are not on Unix. A recursive mutex can be locked twice by the same thread. }}
|
||||
|
||||
{{warning| '''Caution''': be sure that a mutex is unlocked when it is disposed. }}
|
||||
|
||||
{{caution|Be sure that a mutex is unlocked when it is disposed. }}
|
||||
|
||||
|
||||
==The class SEMAPHORE==
|
||||
|
||||
Like <eiffel>MUTEX</eiffel>, the features of this class are mapped on the C thread library. An instance of class <eiffel>SEMAPHORE</eiffel> can be shared between thread.
|
||||
|
||||
|
||||
* Declaration of the semaphore :
|
||||
<code> my_sem: SEMAPHORE</code>
|
||||
|
||||
@@ -88,11 +111,13 @@ Creation of semaphore: initialize semaphore with nb_tokens, it requires nb_token
|
||||
<code> my_sem.try_wait</code>
|
||||
|
||||
|
||||
{{warning| '''Caution''': be sure that a semaphore does not wait for a token when it is disposed }}
|
||||
{{caution|Be sure that a semaphore does not wait for a token when it is disposed }}
|
||||
|
||||
==The class CONDITION_VARIABLE==
|
||||
|
||||
This class allows to use condition variables in Eiffel. An instance of class <eiffel>CONDITION_VARIABLE</eiffel> can be shared between threads.
|
||||
|
||||
|
||||
* Declaration of the condition variable
|
||||
<code> my_cond: CONDITION_VARIABLE</code>
|
||||
|
||||
@@ -106,7 +131,9 @@ This class allows to use condition variables in Eiffel. An instance of class <ei
|
||||
create my_mutex.make
|
||||
</code>
|
||||
|
||||
<code> my_mutex </code> must be locked by the calling thread so as <eiffel>wait</eiffel> can be called. <eiffel>wait</eiffel> atomically unlocks <code> my_mutex </code> and waits for the condition variable <code> my_mutex </code> to receive a signal. As soon as it received a signal, <code> my_cond </code> locks <code> my_mutex </code>;
|
||||
|
||||
<code>my_mutex </code> must be locked by the calling thread so as <eiffel>wait</eiffel> can be called. <eiffel>wait</eiffel> atomically unlocks <code> my_mutex </code> and waits for the condition variable <code> my_mutex </code> to receive a signal. As soon as it received a signal, ''<code>my_cond </code>'' locks ''<code>my_mutex </code>''
|
||||
|
||||
<code>
|
||||
my_mutex.lock
|
||||
-- You must lock `my_mutex' before calling wait.
|
||||
@@ -125,14 +152,17 @@ This class allows to use condition variables in Eiffel. An instance of class <ei
|
||||
* Send a signal to all the threads blocked on the condition variable `my_cond'.
|
||||
<code> my_cond.broadcast</code>
|
||||
|
||||
*
|
||||
{{warning| '''Caution''': be sure that a condition variable is unblocked when it is disposed. }}
|
||||
|
||||
{{caution|Be sure that a condition variable is unblocked when it is disposed. }}
|
||||
|
||||
|
||||
==Miscellaneous classes==
|
||||
|
||||
class <eiffel>THREAD_ATTRIBUTES</eiffel>: defines the attributes of an Eiffel Thread regarding the thread scheduling policy and priority.
|
||||
|
||||
|
||||
==Controlling execution: THREAD_CONTROL==
|
||||
|
||||
* <eiffel>yield</eiffel>: the calling thread yields its execution in favor of an other thread of same priority.
|
||||
* <eiffel>join_all</eiffel>: the calling thread waits for all other threads to finished (all its children).
|
||||
* A parent thread can wait for the termination of a child process through the feature <eiffel>join</eiffel> of class <eiffel>THREAD_CONTROL</eiffel> (inherited by <eiffel>THREAD</eiffel>):
|
||||
@@ -145,15 +175,3 @@ class <eiffel>THREAD_ATTRIBUTES</eiffel>: defines the attributes of an Eiffel Th
|
||||
</code>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[[Property:uuid|f443ed73-14bb-9a3a-b7c7-35c2660e7784]]
|
||||
The EiffelStore library lets the user associate database elements with Eiffel objects. These database elements are basically database table rows, database view rows or more generally sets of database attribute values. The easiest way to manipulate database elements is to insert their content into Eiffel objects and to work on these Eiffel objects as database elements.
|
||||
|
||||
A first solution to implement this is to use some adaptable structures that will fit to any database element. This is done in EiffelStore through the [[ref:libraries/store/reference/db_tuple_flatshort|DB_TUPLE]] class, which contains mainly an [[ref:libraries/base/reference/array_chart|ARRAY]] [[[ref:libraries/base/reference/string_8_chart|STRING]] ] containing element attribute names and an [[ref:libraries/base/reference/array_chart|ARRAY]] [[[ref:libraries/base/reference/any_chart|ANY]] ] containing element attribute values. This solution has one major drawback: any static checking is impossible: the developer cannot be sure at compile time of the nature of a [[ref:libraries/store/reference/db_tuple_flatshort|DB_TUPLE]] , i.e. what it represents, and cannot know if attributes number, names and types are correct. To overcome this problem, a second solution is to use data structures that statically fits to the expected database element, as introduced in the [[Data Object Coupling|DataObject Coupling]] section.
|
||||
A first solution to implement this is to use some adaptable structures that will fit to any database element. This is done in EiffelStore through the [[ref:libraries/store/reference/db_tuple_flatshort|DB_TUPLE]] class, which contains mainly an <code>ARRAY [STRING]</code> containing element attribute names and an <code>ARRAY [ANY]</code> containing element attribute values. This solution has one major drawback: any static checking is impossible: the developer cannot be sure at compile time of the nature of a [[ref:libraries/store/reference/db_tuple_flatshort|DB_TUPLE]] , i.e. what it represents, and cannot know if attributes number, names and types are correct. To overcome this problem, a second solution is to use data structures that statically fits to the expected database element, as introduced in the [[Data Object Coupling|DataObject Coupling]] section.
|
||||
|
||||
The major problem of this technique is that structures are static: one structure, so one class instead of one object, should be created for each database element.
|
||||
|
||||
|
||||
@@ -10,10 +10,6 @@ The abstract [[ref:/libraries/store/reference/database_flatshort|DATABASE]] cla
|
||||
EiffelStore enables to link common interface objects with database-specific implementation objects using a '''handle'''. This handle also enables to switch between different databases.
|
||||
|
||||
Let us see in 4 steps how EiffelStore implements this handle system:
|
||||
* The [[#handle|active database handle]] .
|
||||
* The [[#association|association between interface and implementation]] objects.
|
||||
* The [[#access|access to the DBMS call interface]] from the implementation layer.
|
||||
* The [[#selection|active database selection]] from the database application.0
|
||||
|
||||
==The active database handle==
|
||||
|
||||
|
||||
@@ -34,4 +34,3 @@ Use the [[ref:/libraries/store/reference/db_change_flatshort|DB_CHANGE]] class
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ A [[ref:/libraries/store/reference/db_repository_flatshort|DB_REPOSITORY]] obje
|
||||
end
|
||||
</code>
|
||||
|
||||
|
||||
{{tip|Loading a table description is often a costly operation: table has to be fetched among existing tables then every table column description must be loaded. Hence it is better to store and reuse a repository (maybe with a HASH_TABLE) once it has been loaded. }}
|
||||
|
||||
|
||||
Using the table information, [[ref:/libraries/store/reference/db_repository_flatshort|DB_REPOSITORY]] then helps generating Eiffel classes mapping relational tables:
|
||||
* You can directly use {[[ref:/libraries/store/reference/db_repository_flatshort|DB_REPOSITORY]] }.generate_class. Generated class may look like:
|
||||
<code>
|
||||
@@ -40,6 +42,7 @@ Using the table information, [[ref:/libraries/store/reference/db_repository_flat
|
||||
...
|
||||
</code>
|
||||
|
||||
|
||||
{{note|The EiffelStore Wizard uses the generation.generator cluster to generate the classes mapped to your database. }}
|
||||
|
||||
|
||||
@@ -79,6 +82,7 @@ This is straight-forward since you only have to give [[ref:/libraries/store/refe
|
||||
end
|
||||
</code>
|
||||
|
||||
|
||||
{{note|You can see how actions are used in [[ref:/libraries/store/reference/db_selection_flatshort|DB_SELECTION]] . }}
|
||||
<br/>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[[Property:title|Database Connection]]
|
||||
[[Property:weight|0]]
|
||||
[[Property:uuid|2cf2cb7c-e28d-5d06-b03e-e2b17c1f6879]]
|
||||
# To connect to your database, you have to create a '''handle''': this handle actually links the interface classes with corresponding implementation classes mapped to your DBMS. This handle is implemented by the DATABASE_APPL class:
|
||||
* To connect to your database, you have to create a '''handle''': this handle actually links the interface classes with corresponding implementation classes mapped to your DBMS. This handle is implemented by the DATABASE_APPL class:
|
||||
<code>
|
||||
database_appl: DATABASE_APPL [ODBC]
|
||||
-- Database handle.
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
{{tip|You can manage handles to many databases: as an instance of <eiffel>DATABASE_APPL</eiffel> stands for a specific database handle, you only have to create one instance of <eiffel>DATABASE_APPL</eiffel> for every DBMS handle you wish to create. Do not forget to call set_base to activate appropriate handle. }}
|
||||
|
||||
|
||||
{{note|The generic parameter of <eiffel>DATABASE_APPL</eiffel> specifies the actual DBMS used. }}
|
||||
|
||||
# Once your handle is created, you have to create a session manager which will allow you to manage your database, specifically to establish connection, disconnect and also handle errors. The class <eiffel>DB_CONTROL</eiffel> enables your application to plainly control the functioning and status of your database and to request any information about it.
|
||||
* Once your handle is created, you have to create a session manager which will allow you to manage your database, specifically to establish connection, disconnect and also handle errors. The class <eiffel>DB_CONTROL</eiffel> enables your application to plainly control the functioning and status of your database and to request any information about it.
|
||||
<code>
|
||||
session_control: DB_CONTROL
|
||||
-- Session control.
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
[[Property:weight|7]]
|
||||
[[Property:uuid|432c6e51-36d5-b469-c924-eb821713256a]]
|
||||
Use the [[ref:/libraries/store/reference/db_control_flatshort|DB_CONTROL]] class to check or change database status and behavior. The main operations you are likely to use are:
|
||||
* [[#errors|Handling]] database errors.
|
||||
* [[#connection|Connecting]] to the database.
|
||||
* [[#commit|Committing]] changes in the database.
|
||||
* Handling database errors.
|
||||
* Connecting to the database.
|
||||
* Committing changes in the database.
|
||||
|
||||
==Handling database errors==
|
||||
|
||||
Every EiffelStore interface class has an is_ok feature. This enables to check directly if the last database operation has been successful.
|
||||
|
||||
When an error is detected, you can access through [[ref:/libraries/store/reference/db_control_flatshort|DB_CONTROL]] further information about the error:
|
||||
When an error is detected, you can use [[ref:/libraries/store/reference/db_control_flatshort|DB_CONTROL]] to obtain further information about the error:
|
||||
* error_message provides a description of the error that occurred.
|
||||
* error_code returns a code corresponding to the error type. This code enables to handle specific errors within your code without parsing the error_message.
|
||||
* warning_message provides a warning message about the last transaction performed.
|
||||
@@ -19,7 +19,7 @@ Once you have handled your error, for instance by displaying the error_message o
|
||||
|
||||
==Managing database connection==
|
||||
|
||||
[[ref:/libraries/store/reference/db_control_flatshort|DB_CONTROL]] lets you connect, check connection and disconnect from the database.
|
||||
[[ref:/libraries/store/reference/db_control_flatshort|DB_CONTROL]] lets you connect, check your connection, and disconnect from the database.
|
||||
|
||||
The following example sum up these capabilities:
|
||||
<code>
|
||||
@@ -34,9 +34,9 @@ The following example sum up these capabilities:
|
||||
|
||||
==Committing changes in the database==
|
||||
|
||||
Every modification you do in the database are usually not directly saved. This enables to limit damage caused by mishandlings. You can then manage database modification through 2 commands:
|
||||
With many database systems, modifications you make to the database are usually not saved immediately. Rather, changes are accumulated in a "transaction". At some point the entire transaction is committed to the database (i.e., the changes are actually made to the data) or the entire transaction is rolled back (i.e., absolutely no changes are made to the data.) You can manage database modification through 2 commands:
|
||||
* ''Commit'' saves the changes in the database.
|
||||
* ''Rollback'' restores the database content corresponding to last commitment.
|
||||
* ''Rollback'' restores the database content to its state after the most recent commit.
|
||||
|
||||
The following example illustrates the use of these commands:
|
||||
<code>
|
||||
@@ -57,7 +57,7 @@ The following example illustrates the use of these commands:
|
||||
|
||||
The loop performs a multi-step transaction. If transaction is not carried out entirely, the database could stay in an invalid state: this code ensures that database remains in a valid state.
|
||||
|
||||
{{warning| '''Caution''': Some databases can be in an auto-commit mode. Furthermore, some special database commands can automatically commit database changes. }}
|
||||
{{caution|Some databases can be in an auto-commit mode. Furthermore, some special database commands can automatically commit database changes. }}
|
||||
|
||||
{{seealso|<br/>
|
||||
[[Database Connection|Database connection]] <br/>
|
||||
|
||||
@@ -3,21 +3,7 @@
|
||||
[[Property:uuid|abd6c880-e0d8-0961-8cd2-d2ca43c1ce28]]
|
||||
The Interface layer gathers a set of classes covering all the capabilities an application need to interface efficiently with a DBMS.
|
||||
|
||||
The interface affords these main capabilities:
|
||||
* [[Database Connection|Connecting]] to the database.
|
||||
* [[Data Modification|Modifying]] database objects.
|
||||
* [[Database Selection|Selecting]] data from the database.
|
||||
* [[Selection Access|Accessing]] data selected from the database.
|
||||
* [[Data Object Coupling|Coupling]] database objects with Eiffel objects.
|
||||
* [[Query variables|Binding variables]] in a database query.
|
||||
* Using [[Stored Procedures|stored procedures]] .
|
||||
* Dealing with database [[Database control|status and behavior]] .
|
||||
|
||||
{{note|In general, each of these capabilities corresponds to one EiffelStore class. }}
|
||||
|
||||
{{seealso|<br/>
|
||||
[[EiffelStore Implementation Layer|The implementation layer]] }}
|
||||
|
||||
Each of the following sections describes a particular database capability accessed through the EiffelStore interface layer. In general, each of these capabilities is made available in the interface layer by one class.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[[Property:uuid|3b4fdde3-d903-55c8-0068-cee2407db280]]
|
||||
Once you have [[Database Selection|selected data]] from the database, it returns a set of rows containing queried columns values. Each row loaded with DB_SELECTION is stored in a DB_RESULT object. The easiest way to access the data is thus to refer to DB_RESULT objects themselves.
|
||||
|
||||
|
||||
{{note|Take a look at the [[Data Object Coupling|Database/Eiffel objects Coupling]] to learn advanced data handling features. }}
|
||||
|
||||
To use DB_RESULT, process in 2 steps:
|
||||
@@ -64,7 +65,6 @@ To use DB_RESULT, process in 2 steps:
|
||||
Result := i >= Max_result
|
||||
end
|
||||
</code>
|
||||
|
||||
** Then set action to [[ref:/libraries/store/reference/db_selection_flatshort|DB_SELECTION]] :
|
||||
<code>
|
||||
selection: DB_SELECTION
|
||||
@@ -93,6 +93,7 @@ A DB_RESULT object merely carries data retrieved from the database. You have to
|
||||
end
|
||||
</code>
|
||||
|
||||
|
||||
{{seealso|<br/>
|
||||
[[Database Selection|Performing a database selection.]] <br/>
|
||||
[[Data Object Coupling|Coupling database data and Eiffel objects.]] <br/>
|
||||
@@ -100,5 +101,3 @@ A DB_RESULT object merely carries data retrieved from the database. You have to
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,10 +22,13 @@ To execute a stored procedure:
|
||||
</code>
|
||||
|
||||
* Execute the procedure through a [[ref:/libraries/store/reference/db_selection_chart|DB_SELECTION]] (if a result is expected) or a [[ref:/libraries/store/reference/db_change_chart|DB_CHANGE ]] object (otherwise).
|
||||
|
||||
{{note|Requests with a result ([[ref:/libraries/store/reference/db_selection_chart|DB_SELECTION]] ) or without ([[ref:/libraries/store/reference/db_change_chart|DB_CHANGE]] ) are both abstract '''expressions'''. DB_PROC executes an abstract expression using an object of [[ref:/libraries/store/reference/db_expression_chart|DB_EXPRESSION]] type, which corresponds to an abstract expression. [[ref:/libraries/store/reference/db_selection_chart|DB_SELECTION]] and [[ref:/libraries/store/reference/db_change_chart|DB_CHANGE]] inherits from [[ref:/libraries/store/reference/db_expression_chart|DB_EXPRESSION]] . }}
|
||||
|
||||
You can execute your request mostly like a basic one:
|
||||
** Create your request.
|
||||
** Bind request variables. Variables are stored procedure arguments.
|
||||
|
||||
{{note|Take a look at how to [[Query variables|bind variables]] to a query. }}
|
||||
|
||||
** Execute the query through the DB_PROC object.
|
||||
@@ -62,6 +65,7 @@ The following example shows how to overwrite a procedure in the database:
|
||||
end
|
||||
</code>
|
||||
|
||||
|
||||
{{seealso|<br/>
|
||||
[[Database Selection|Performing a database selection.]] <br/>
|
||||
[[Data Object Coupling|Coupling database data and Eiffel objects.]] <br/>
|
||||
|
||||
@@ -9,6 +9,3 @@ Other cluster can facilitate your database management:
|
||||
* The [[EiffelStore Generation Cluster|generation cluster]] , with the EiffelStore wizard, generates a facilitated and dynamic interface with your database.
|
||||
* The [[EiffelStore DataView Cluster|dataview cluster]] lets you create a customized database GUI.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
[[Property:uuid|c9c0fe01-a80f-5834-8503-aad1063e1503]]
|
||||
=Description=
|
||||
|
||||
Here is a set of five examples written thanks to the EiffelNet library to show some basic applications. Two of them (Advanced and Same Machine) rely on specific code to Unix Operating systems and consequently cannot be run under Windows.
|
||||
Here is a set of five examples written to show some basic applications using the EiffelNet library . Two of them (Advanced and Same Machine) rely on specific code to Unix Operating systems and consequently cannot be run under Windows.
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
[[Property:title|Bibliography]]
|
||||
[[Property:weight|10]]
|
||||
[[Property:uuid|739d59a6-c0b0-899f-24cf-5a17655a5512]]
|
||||
[1] Bertrand Meyer: [http://www.eiffel.com/doc/] , Prentice Hall, 1992. (Available from Eiffel Software.)
|
||||
[2] Bertrand Meyer: [http://www.eiffel.com/doc/] , Prentice Hall, 1994. (Available from Eiffel Software.)
|
||||
[1] Bertrand Meyer: [http://www.eiffel.com/doc/#etl Eiffel: The Language], Prentice Hall, 1992. (Available from Eiffel Software.)
|
||||
|
||||
|
||||
[2] Bertrand Meyer: [http://www.eiffel.com/doc/#ru Reusable Software: The Base Object-Oriented Component Libraries], Prentice Hall, 1994. (Available from Eiffel Software.)
|
||||
|
||||
|
||||
[3] W. Richard Stevens: ''Unix Network Programming'', Prentice Hall, 1990.
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
[[Property:title|Event-driven command execution]]
|
||||
[[Property:weight|8]]
|
||||
[[Property:uuid|66036773-3e41-2877-7fa4-e0601558fc7c]]
|
||||
{| border="1"
|
||||
|-
|
||||
| The example classes discussed in this section appear in the subdirectory ''polling ''of the example directory
|
||||
|}
|
||||
{{note|The example classes discussed in this section appear in the subdirectory ''polling ''of the example directory.}}
|
||||
|
||||
|
||||
===9.1 Commands and events===
|
||||
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
[[Property:title|EiffelNet Tutorial]]
|
||||
[[Property:weight|0]]
|
||||
[[Property:uuid|09679e98-4d5c-d2af-439b-00b28c6cfe4b]]
|
||||
* [[What is EiffelNet|Introduction]]
|
||||
* [[Clients and servers|Clients and server]]
|
||||
* [[An overview of EiffelNet Mechanisms|An overview of EiffelNet mechanisms]]
|
||||
* [[The predefined level|The predefined level]]
|
||||
* [[Introduction to the examples|Introduction to the examples]]
|
||||
* [[Working at predefined level|Working at the predefined level]]
|
||||
* [[Obtaining a finer degree of control|Obtaining a finer degree of control]]
|
||||
* [[Using datagram sockets|Using datagram sockets]]
|
||||
* [[Event-driven command execution|Event-driven command execution]]
|
||||
* [[A more complex example|A more complex example]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ The examples start with the most simple uses involving high-level classes coveri
|
||||
|
||||
All the examples discussed here appear in the directory ''$ISE_EIFFEL/examples/net'' of the Eiffel distribution.
|
||||
|
||||
{{warning| '''Caution''': On Windows, the `advanced' and the `same_mach' are not working since they are using specific code to Unix Operating systems. }}
|
||||
{{caution|On Windows, the examples `advanced' and the `same_mach' are nonfunctional. This is because these examples use code specific to Unix Operating systems. }}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
[[Property:title|A more complex example]]
|
||||
[[Property:weight|9]]
|
||||
[[Property:uuid|a57bbf5b-d877-8a50-1bca-92848868bdec]]
|
||||
{| border="1"
|
||||
|-
|
||||
| The example classes discussed in this section appear in the subdirectory ''advanced ''of the example directory
|
||||
|}
|
||||
{{note|The example classes discussed in this section appear in the subdirectory ''advanced ''of the example directory.}}
|
||||
|
||||
|
||||
The last example exercises most of EiffelNet's major facilities. It consists of a server that allows an arbitrary number of clients to connect to it. Each time the user of one of the client systems types a line on the keyboard, the client sends this character to the server, which then broadcasts it to all the clients (including the original sender). This scheme allows several people to talk together, hence the names chosen: the server class is called <code> CHAT </code>, and the client is called <code> JOIN </code>.
|
||||
|
||||
|
||||
@@ -165,10 +165,8 @@ Here now is the client class:
|
||||
</code>
|
||||
|
||||
===Communication between two different machines===
|
||||
{| border="1"
|
||||
|-
|
||||
| The example classes discussed in this section appear in the subdirectory ''two_mach ''of the example directory
|
||||
|}
|
||||
{{note|The example classes discussed in this section appear in the subdirectory ''two_mach ''of the example directory }}
|
||||
|
||||
|
||||
Let us now assume that the client and the server will run on two separate machines. Instead of UNIX_ sockets, we must now use sockets of type <code>NETWORK_STREAM_SOCKET</code>.
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
[[Property:title|Using datagram sockets]]
|
||||
[[Property:weight|7]]
|
||||
[[Property:uuid|ba27b7dd-77db-7f6f-9b8c-2a3111d9d432]]
|
||||
{| border="1"
|
||||
|-
|
||||
| The example classes discussed in this section appear in the subdirectory ''datagram ''of the example directory
|
||||
|}
|
||||
{{note|The example classes discussed in this section appear in the subdirectory ''datagram ''of the example directory. }}
|
||||
|
||||
Using datagram sockets implies a few differences from the preceding schemes. You create a [[ref:libraries/net/reference/network_datagram_socket_chart|NETWORK_DATAGRAM_SOCKET]] or a <eiffel>UNIX_DATAGRAM_SOCKET</eiffel> as before. You do not need to call ''listen'', ''accept'' or ''connect''. Once you have created your sockets using the ''make_client ''or ''make_server'' creation procedure, you can use the ''send ''and ''received ''routines, specifying the socket to which you want to send, or from which you want to receive.
|
||||
|
||||
|
||||
@@ -1,33 +1,5 @@
|
||||
[[Property:title|CECIL Reference]]
|
||||
[[Property:weight|4]]
|
||||
[[Property:uuid|20ca6ef1-0d26-a556-955c-96bed93dfdfb]]
|
||||
Index of CECIL features
|
||||
* [[Reference for `RTMS'|RTMS()]]
|
||||
* [[Reference for `attribute_exists'|attribute_exists()]]
|
||||
* [[Reference for `eif_adopt'|eif_adopt()]]
|
||||
* [[Reference for `eif_attribute'.|eif_attribute()]]
|
||||
* [[Reference for `eif_attribute_type'|eif_attribute_type()]]
|
||||
* [[Reference for `eif_bit_function'|eif_bit_function()]]
|
||||
* [[Reference for 'eif_boolean_function'|eif_boolean_function()]]
|
||||
* [[Reference for `eif_character_function'|eif_character_function()]]
|
||||
* [[Reference for `eif_disable_visible_exception'|eif_disable_visible_exception()]]
|
||||
* [[Reference for `eif_double_function'|eif_double_function()]]
|
||||
* [[Reference for `eif_enable_visible_exception'|eif_enable_visible_exception()]]
|
||||
* [[Reference for `eif_integer_function'|eif_integer_function()]]
|
||||
* [[Reference for `eif_name'|eif_name()]]
|
||||
* [[Reference for `eif_name_by_tid'|eif_name_by_tid()]]
|
||||
* [[Reference for `eif_pointer_function'|eif_pointer_function()]]
|
||||
* [[Reference for `eif_procedure'|eif_procedure()]]
|
||||
* [[Reference for `eif_protect'|eif_protect()]]
|
||||
* [[Reference for `eif_real_function'|eif_real_function()]]
|
||||
* [[Reference for `eif_reference_function'|eif_reference_function()]]
|
||||
* [[Reference for `eif_string'|eif_string()]]
|
||||
* [[Reference for `eif_type'|eif_type()]]
|
||||
* [[Reference for `eif_type_by_name'|eif_type_by_name()]]
|
||||
* [[Reference for `eif_type_by_reference'|eif_type_by_reference()]]
|
||||
* [[Reference for `eif_type_id'|eif_type_id()]]
|
||||
* [[Reference for `eif_wean'|eif_wean()]]
|
||||
|
||||
|
||||
|
||||
References for CECIL features
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Note that through CECIL you can use an Eiffel system compiled in any of the Eiff
|
||||
|
||||
{{note|each time you melt the Eiffel system, the ''<system name>. melted'' file is updated. }}
|
||||
|
||||
{{warning| '''Caution''': in the second case (workbench mode), it is not possible to call through the CECIL interface any routine that has been melted in the last compilation; this would raise the run-time exception: <br/>
|
||||
{{caution|In the second case (workbench mode), it is not possible to call through the CECIL interface any routine that has been melted in the last compilation; this would raise the run-time exception: <br/>
|
||||
''' $ applied to melted routine''' <br/>
|
||||
The solution is simply to refreeze the system. }}
|
||||
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
[[Property:title|CECIL]]
|
||||
[[Property:weight|3]]
|
||||
[[Property:uuid|c03112b8-578e-cc1a-ee13-c6928b787529]]
|
||||
* [[CECIL: Introduction|Introduction]]
|
||||
* [[Compiling an Eiffel system for CECIL|Compiling an Eiffel system for CECIL]]
|
||||
* [[Using a CECIL archive|Using a CECIL archive]]
|
||||
* [[CECIL interface overview|CECIL interface overview]]
|
||||
* [[CECIL Reference|CECIL man pages]]
|
||||
* [[CECIL samples|CECIL examples]]
|
||||
This document provides an overview of the C-Eiffel Call-In Library (CECIL) as defined in Eiffel: The Language (ETL). The first section addresses how to compile and run a CECIL program, on the [[Compiling an Eiffel system for CECIL|Eiffel side]] and on the [[Using a CECIL archive|C side]] . The [[CECIL interface overview|second part]] contains a more precise description of the Eiffel types, the protection mechanism as well as how to write and use C externals.
|
||||
|
||||
CECIL, designed by Eiffel Software , is the C library that permits C and C++ applications (as well as applications written in other languages) to take advantage of almost all Eiffel facilities: create Eiffel objects, apply features to them. The basics of CECIL are described in chapter 24 of the reference book on Eiffel, Eiffel: The Language, which covers interfaces between Eiffel and other languages. Important material can also be found in the Eiffel Software manual Eiffel: The Environment.
|
||||
|
||||
The CECIL documentation, man pages and examples are part of the standard delivery of EiffelStudio 5.0 and higher.
|
||||
|
||||
The present document complements the descriptions of Eiffel: The Language. Note that CECIL has been revised and improved since that book was published, so the explanations below have precedence over those in the book.
|
||||
|
||||
This document is intended for both Windows and Unix users. Only a few of the sections, clearly marked, are platform-specific.
|
||||
To access Eiffel mechanisms from C or other external languages:
|
||||
* Compile your Eiffel system so as to generate "Cecilized" code, that is to say code callable from the outside. See [[Compiling an Eiffel system for CECIL|Compiling your Eiffel system for CECIL]] .
|
||||
* In writing the external code that will use the facilities of the Eiffel system, use the CECIL functions as specified in chapter 24 of ''Eiffel: The Language''. See also [[CECIL interface overview|The CECIL interface overview]] .
|
||||
* C-compile and link that code. See [[Using a CECIL archive|Building a C system using CECIL]] .
|
||||
|
||||
For feature by feature specification, please have a look at [[CECIL Reference|the man pages]] .
|
||||
|
||||
|
||||
@@ -2,54 +2,79 @@
|
||||
[[Property:weight|2]]
|
||||
[[Property:uuid|e8438c9b-65ae-368f-6559-a0d5b28db4b7]]
|
||||
==Linking the CECIL archive into a program==
|
||||
The CECIL archive already incorporates the Eiffel run-time. To use the functions provided in the CECIL archive, simply write the C programs according to the CECIL specifications of ETL, and then include the CECIL archive in the link line of your C application. This line looks like:
|
||||
on Unix/linux:
|
||||
The CECIL archive already incorporates the Eiffel run-time. To use the functions provided in the CECIL archive, simply write the C programs according to the CECIL specifications of ETL, and then include the CECIL archive in the link line of your C application.
|
||||
|
||||
|
||||
On Unix/linux, this line looks like this:
|
||||
|
||||
|
||||
<code>ld -o [name of your CECIL executable] [your C object files and archives]lib<system name>.a -lm</code>
|
||||
|
||||
|
||||
{{note|On Unix, linking with "-lm" is required since the Eiffel run-time uses the standard math libraries. You may need to link with other libraries (for example, on linux: with "-lbsd", in MT mode with "-lpthread" (posix threads) or "-lthread" (solaris)). }}
|
||||
|
||||
|
||||
|
||||
on Windows, with MS VC++:
|
||||
|
||||
|
||||
<code>link [your link flags] -OUT:[name of your cecil executable] [your C object files and archives] lib<system name>.lib [other Windows libraries]</code>
|
||||
|
||||
|
||||
|
||||
on Windows with Borland:
|
||||
|
||||
|
||||
<code>ilink32 -ap -c -Tpe main.obj c0w32.obj, [name of your cecil executable],,EIFGENs\target_name\W_code\lib<system name>.lib CW32 IMPORT32 OLE2w32,,</code>
|
||||
|
||||
|
||||
|
||||
'''Notes for compiling CECIL C files:''' <br/>
|
||||
===Notes for compiling CECIL C files:===
|
||||
The CECIL library is built automatically, which is unfortunately not the case of the corresponding object files of the cecil program you wrote. <br/>
|
||||
The C flags to use are usually the same as the ones needed during the compilation of the generated C-code plus those which are relevant to your own C-code.
|
||||
|
||||
Typically, you will compile with your flags as below (if you are using gcc):
|
||||
|
||||
|
||||
<code>gcc -c -O -I$ISE_EIFFEL/studio/spec/$PLATFORM/include -I<SOME_INCLUDE_PATH> -D<SOME_FLAGS> your_file.c</code>
|
||||
|
||||
|
||||
or , if you are on Windows using MS VC++:
|
||||
|
||||
|
||||
<code>cl -c -nologo -Ox -I$ISE_EIFFEL\studio\spec\windows\include -I<SOME_INCLUDE_PATH> -D<SOME_FLAGS> your_file.c</code>
|
||||
|
||||
|
||||
or, if you are on Windows using Borland:
|
||||
|
||||
|
||||
<code>bcc32 -c -I$ISE_EIFFEL\studio\spec\windows\include -I<SOME_INCLUDE_PATH> -D<SOME_FLAGS> your_file.c</code>
|
||||
|
||||
{{sample|if you want to use the multithreaded facilities of Eiffel, you should define the EIFFEL MT flags by adding "-DEIF_THREADS" to the command line and follow the instructions of your C compiler and platform to find out which additional flags you may need '''. For example:''' on Solaris you need to add "-DSOLARIS_THREADS -D_REENTRANT". }}
|
||||
|
||||
{{note|if you want to use the multithreaded facilities of Eiffel, you should define the EIFFEL MT flags by adding "-DEIF_THREADS" to the command line and follow the instructions of your C compiler and platform to find out which additional flags you may need. For example, on Solaris you need to add "-DSOLARIS_THREADS -D_REENTRANT". }}
|
||||
|
||||
|
||||
You can specify a Makefile in your configuration file, so that your C files will be compiled automatically after the Eiffel compilation and before the final linking. See [[Externals Options|the manipulation of external]] in the project settings to add <code>$PATH_TO_MAKEFILE/your_makefile</code>.
|
||||
|
||||
|
||||
This makefile will be run from the $/EIFGENs/target_name/W_code or $/EIFGENs/target_name/F_code directory. You should not give the CECIL executable the same name as your system, because it will be replaced by the Eiffel executable when you run another compilation.
|
||||
|
||||
|
||||
==Initializing the Eiffel run-time==
|
||||
Even though the main thread of control resides in the "C side" of the program, the Eiffel run-time must be initialized correctly before it can use CECIL facilities to communicate with the Eiffel world.
|
||||
In the C file containing the "main" C function, you must add the following line to include the header file "eif_setup. h" provided with this example:
|
||||
|
||||
|
||||
<code>
|
||||
#include "eif_setup.h" /* Macros EIF_INITIALIZE and EIF_DISPOSE_ALL */
|
||||
#include "eif_eiffel.h" /* Exported functions of the Eiffel run-time */</code>
|
||||
|
||||
|
||||
Your "main" function must have the three standard arguments of the C "main" function: "argc", "argv" and "envp" and include the following macros that are defined in "eif_setup. h":
|
||||
|
||||
|
||||
<code>
|
||||
int main(int argc, char **argv, char **envp)
|
||||
/* Please respect this signature: `argc', `argv' and `envp' are used * in EIF_INITIALIZE. */
|
||||
/* Please respect this signature: 'argc', 'argv' and 'envp' are used * in EIF_INITIALIZE. */
|
||||
{
|
||||
/* declarations of variables */
|
||||
/* Initialize the Eiffel run-time. */
|
||||
@@ -61,10 +86,11 @@ int main(int argc, char **argv, char **envp)
|
||||
EIF_DISPOSE_ALL
|
||||
}</code>
|
||||
|
||||
{{note|s''': <br/>
|
||||
The above mentioned macros must imperatively be in the body of the "main" function for the Eiffel exception handling mechanism to work correctly. You also need to add the Eiffel run time directory to the list of directories in which the C compiler searches for include files. You can do so by using the "-I" option of your C compiler. You can only link one CECIL library into your C applications at a time. }}
|
||||
|
||||
{{warning| '''Caution''': Even though external object files and archives are correctly specified in the "object" clause of the configuration file, you will need to explicitly link them to your C application. }}
|
||||
{{note|The above mentioned macros must imperatively be in the body of the "main" function for the Eiffel exception handling mechanism to work correctly. You also need to add the Eiffel run time directory to the list of directories in which the C compiler searches for include files. You can do so by using the "-I" option of your C compiler. You can only link one CECIL library into your C applications at a time. }}
|
||||
|
||||
|
||||
{{caution|Even though external object files and archives are correctly specified in the "object" clause of the configuration file, you will need to explicitly link them to your C application. }}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ The C++/Eiffel interface offers the following mechanisms:
|
||||
* You can apply to these objects all the corresponding operations from the C++ class: executing functions ("methods"), accessing data members, executing destructors.
|
||||
* On Windows, you can use the Legacy++ tool to produce an Eiffel "wrapper class" encapsulating all the features of a C++ class, so that the result will look to the rest of the Eiffel software as if it had been written in Eiffel.
|
||||
|
||||
The discussion concentrates on using C++ software from Eiffel. In the other direction, you can use [[CECIL: Introduction|the Cecil library (C-Eiffel Call-In Library)]] .
|
||||
The discussion concentrates on using C++ software from Eiffel. In the other direction, you can use [[CECIL|the Cecil library (C-Eiffel Call-In Library)]] .
|
||||
|
||||
==Syntax specification==
|
||||
|
||||
|
||||
@@ -7,12 +7,14 @@ As Eiffel Software's technology relies heavily on the use of a C/C++ ANSI compil
|
||||
|
||||
The sections concerning [[#macros|Macros]] and [[#structs|Structs]] are also available for C++ if the macro or the struct is defined in a C++ header file.
|
||||
<span id="C"></span>
|
||||
|
||||
|
||||
==C routines==
|
||||
|
||||
You can encapsulate routines that are defined in a C header file. We will take some examples and will show you how to write wrappers in Eiffel.
|
||||
|
||||
If in a header file called `my_header.h', you have the following declaration:
|
||||
<code>
|
||||
<code lang="c">
|
||||
/* Routine with no parameter */
|
||||
extern void no_param(void);
|
||||
|
||||
@@ -25,6 +27,7 @@ extern size_t no_param_return(void);
|
||||
/* Routine returning a value with one parameter */
|
||||
extern size_t one_param_return(FILE *f);</code>
|
||||
|
||||
|
||||
Here is the corresponding Eiffel code:
|
||||
<code>
|
||||
c_no_param is
|
||||
@@ -61,18 +64,23 @@ Here is the corresponding Eiffel code:
|
||||
"one_param_return"
|
||||
end</code>
|
||||
<span id="macros"></span>
|
||||
|
||||
|
||||
==Macros==
|
||||
|
||||
If in a header file called `my_header.h', you have the following declaration:
|
||||
<code>
|
||||
<code lang="c">
|
||||
/* Predefined constants */
|
||||
#define ID_MENU 128
|
||||
#define ID_MENU_CHARACTER 'c'
|
||||
|
||||
/* Access the `i'-th element of `a' where `a' * is an array of EIF_INTEGER */
|
||||
/* Access the 'i'-th element of 'a' where 'a' * is an array of EIF_INTEGER */
|
||||
#define i_th(a,i)((a) + (i)*sizeof(EIF_INTEGER))</code>
|
||||
|
||||
|
||||
Then, the corresponding Eiffel code will look like:
|
||||
|
||||
|
||||
<code>
|
||||
menu_id: INTEGER is
|
||||
-- `ID_MENU' C encapsulation.
|
||||
@@ -98,18 +106,23 @@ Then, the corresponding Eiffel code will look like:
|
||||
"i_th"
|
||||
end</code>
|
||||
<span id="structs"></span>
|
||||
|
||||
|
||||
==Structs==
|
||||
|
||||
The struct encapsulation enables you to wrap C/C++ structures easily without having to write any additional code in a C header file as it was the case until Eiffel Software introduced this new keyword in the external specification with the 4.5 release of the Eiffel Software environment. With the struct encapsulation you can set and retrieve the value of a certain field of a struct.
|
||||
|
||||
If in a header file called `my_header.h', you have the following declaration of the `Point' structure whose `x' and `y' fields we want to access and set:
|
||||
<code>
|
||||
|
||||
|
||||
<code lang="c">
|
||||
/* Definition of `Point' */
|
||||
typdef struct point {
|
||||
int x;
|
||||
int y;
|
||||
} Point;</code>
|
||||
|
||||
|
||||
Then, the corresponding Eiffel code will look like:
|
||||
<code>
|
||||
x (p: POINTER): INTEGER is
|
||||
@@ -144,6 +157,8 @@ Then, the corresponding Eiffel code will look like:
|
||||
"y"
|
||||
end</code>
|
||||
<span id="windows"></span>
|
||||
|
||||
|
||||
==Windows externals==
|
||||
|
||||
===DLLs===
|
||||
@@ -153,6 +168,8 @@ With EiffelStudio you now have two different ways to call C routines exported in
|
||||
* __stdcall referred to as the Pascal way
|
||||
|
||||
Therefore if you want to call an external routine defined in a DLL supposed to be called using the `_cdecl' method, you have to use the '''dll32''' sub-language option. For `__stdcall' you need to use the '''dllwin32''' sub-language option. Here is an example:
|
||||
|
||||
|
||||
<code>
|
||||
my_cdecl_routine (a: INTEGER): POINTER is
|
||||
-- Encapsulation of a dll function with the `_cdecl' call mechanism.
|
||||
@@ -166,7 +183,9 @@ Therefore if you want to call an external routine defined in a DLL supposed to b
|
||||
"C [dllwin32 %"my_dll.dll%"] (int): EIF_POINTER"
|
||||
end</code>
|
||||
|
||||
{{warning| '''Caution''': Using wrongly '''dll32''' instead of '''dllwin32''' and reciprocally will conduce to a crash of your system since the C call stack will be corrupted. For more information please read your C compiler documentation. }}
|
||||
|
||||
{{warning|Using '''dll32''' in cases calling for '''dllwin32''' and vice versa will cause your system to crash, because the C call stack will be corrupted. For more information please read your C compiler documentation. }}
|
||||
|
||||
|
||||
===Windows API===
|
||||
|
||||
@@ -174,13 +193,19 @@ As described in the previous section concerning routines exported in a DLL, the
|
||||
|
||||
Here is an example that has been taken from WEL, the Windows Eiffel Library, to encapsulate the Windows `SendMessage' function:
|
||||
Windows defined SendMessage as:
|
||||
<code>LRESULT SendMessage(
|
||||
|
||||
|
||||
<code lang="cpp">LRESULT SendMessage(
|
||||
HWND hWnd, // handle to destination window
|
||||
UINT Msg, // message
|
||||
WPARAM wParam, // first message parameter
|
||||
LPARAM lParam // second message parameter
|
||||
);</code>
|
||||
|
||||
|
||||
In WEL, the encapsulation is written as:
|
||||
|
||||
|
||||
<code>
|
||||
cwin_send_message (hwnd: POINTER; msg, wparam, param: INTEGER) is
|
||||
-- SDK SendMessage (without the result)
|
||||
@@ -190,6 +215,7 @@ In WEL, the encapsulation is written as:
|
||||
"SendMessage"
|
||||
end</code>
|
||||
|
||||
|
||||
{{seealso|<br/>
|
||||
[[C++ Externals|C++ externals]] }}
|
||||
|
||||
|
||||
@@ -12,5 +12,3 @@ It is also possible to make Eiffel routines available to be called by these lang
|
||||
===Microsoft COM and .NET===
|
||||
In addition to C, C++, and Java, you may find it valuable to use Eiffel with other technologies like Microsoft COM and the multiple languages of Microsoft .NET. You will find information about interacting with these technologies in our documentation specific to [[Windows|support for Microsoft Windows]].
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user