Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc

Blog Rupra a Engina

Programovat znamená 2 hodiny přemýšlet jak to za 5 minut osr* ehm vyběhnout.
Off Topic(!!!): Co je to platforma

Engin (10:57 AM) :

Q: co je to platforma?

Romeo (10:58 AM) :

to je takové stupátko co se připne za kočárek. Má vlastní kolečka a druhé dítě na ní stojí

Engin (10:58 AM) :

to mě p****

Romeo (10:58 AM) :

ne díky

Engin (10:58 AM) :

takže to potvrzuje moji teorii že je to slovo které používají všichni na všechno

Romeo (10:59 AM) :

ne jenom na kočárek a na těžbu ropy :-)

Romeo (11:00 AM) :

každopádně, pokud nevíš co je platforma, tak by ses nad sebou měl vážně zamyslet :-)

Engin (11:00 AM) :

kéž by

Engin (11:00 AM) :

.NET je flatforma pro běh .NET aplikací

Romeo (11:00 AM) :

na platformě windows :-D

Engin (11:00 AM) :

funambol je platforma využívající syncml protokol

Engin (11:01 AM) :

všechno je platforma

Engin (11:01 AM) :

platforma je všechno :-)

Engin (11:01 AM) :

http://www.platforma.cz/

Engin (11:01 AM) :

:-D

Romeo (11:01 AM) :

platforma je platforma která používá platformu na platformě platforma.

Engin (11:02 AM) :

railway platform

Engin (11:02 AM) :

http://en.wikipedia.org/wiki/Platform_%28computing%29

Romeo (11:02 AM) :

když je platforma všechno, tak vlastně ani nepotřebujeme jiné slova

Engin (11:02 AM) :

žejo

Romeo (11:02 AM) :

prostě platforma

Engin (11:02 AM) :

ješt že nám to zasílací platforma ICQ tak heky funguje

Engin (11:02 AM) :

platforma

Engin (11:02 AM) :

dy deš na platformu?

Engin (11:03 AM) :

plat-forma :-)

Romeo (11:03 AM) :

platforma bude za platformu.

Romeo (11:04 AM) :

áíčíářáéářčáář.NET 3.5 Windows(x86) 197MB

Romeo (11:04 AM) :

ty ****

Romeo (11:04 AM) :

teda ty platformo

Engin (11:04 AM) :

no, to je ale platforma

Engin (11:04 AM) :

:-)

Romeo (11:04 AM) :

jak platforma

Engin (11:04 AM) :

vítej. nedávno sem ti říkal, že sem nenašel redist platformu pro platformu .net 3.5

Romeo (11:05 AM) :

BTW potřebujeme i jiné slovní druhy jak podstatné jméno platforma?

Romeo (11:05 AM) :

když není jiné jméno, tak jsou ostatní druhy taky naprd ne?

Romeo (11:05 AM) :

takže spojení jako:

Kdy jdeš na platformu?

Máš platformu?

Co za platformu máš na platformě.

Romeo (11:06 AM) :

je k prdu.

Engin (11:06 AM) :

bys nemohl popsat co s tou platformou všechno můžeš dělat

Romeo (11:06 AM) :

taky skloňování je k prdu.

Engin (11:06 AM) :

to je pravda

Romeo (11:06 AM) :

Ale interpunkci bych nechal

Engin (11:06 AM) :

takže z původní konverzace zbyde:

platforma?

platforma?

platforma platforma.

Romeo (11:06 AM) :

vzniklo by pak něco jako :

Platforma?

Platforma

Engin (11:06 AM) :

platformáa !!!!!

Romeo (11:06 AM) :

platforma

Engin (11:07 AM) :

ty, hele

Engin (11:07 AM) :

ješt ano/ne bychom mohli nechat

Engin (11:07 AM) :

nebo negaci?

Engin (11:07 AM) :

! Platforma

Romeo (11:07 AM) :

opak platformy je platforma ne?

Engin (11:07 AM) :

no, jo, ale chybyí mi prostředek jak vyjádřit nesouhlas s platformou

Engin (11:08 AM) :

i když to je vlasně popření všeho bytí, co? =-O

Romeo (11:08 AM) :

když budeš mít souhlas ano, a nesouhlas ne, tak si představ, že ti někdo vezme ne, takže budeš mít souhlas ano a nesouhlas ano :-)

Engin (11:08 AM) :

všeho platformování

Romeo (11:08 AM) :

takže opak platformy je platformy.

Romeo (11:08 AM) :

BTW představ si ty básničky.

Romeo (11:08 AM) :

absoluní rým.

Romeo (11:08 AM) :

ne knížky :-D

Engin (11:09 AM) :

nebo třeba takový recept ;-)

Engin (11:09 AM) :

nebo popiš mi svoje auto:

Romeo (11:09 AM) :

platforma

Romeo (11:09 AM) :

recept je v poho koupíš platformu a dáš do ní platformu. Vznikne ti platforma.

Romeo (11:10 AM) :

Nemůžeš nic zkazit.

Romeo (11:10 AM) :

vem si kolik ušetříš času v obchodě a restauraci.

Engin (11:10 AM) :

tojo, ale potřebuješ kapky na rýmu a dostaneš čípky do zadku, protože obojí je platforma

Romeo (11:10 AM) :

nebudeš muset číst jídelní lístek. prostě si dáš platfrormu

Engin (11:10 AM) :

možná bychom mohli odlišovat jak se to řekne, jako intonaci

Romeo (11:10 AM) :

jak číňani :-)

Engin (11:10 AM) :

ale to bychom zase museli njak zapisovat, třeba tečkama a dvojtečkama

Romeo (11:11 AM) :

nebo křováci

Engin (11:11 AM) :

pla:t::fo/r/::///ma!!!

Romeo (11:11 AM) :

ne tečky ani dvojtečky nebou potřeba stačí když tam vrazíš platformy

Engin (11:11 AM) :

ty hele

pla(platforma)t(fo(platforma)r(platforma platforma platforma platforma platforma platforma)ma

Romeo (11:11 AM) :

co vznikne, když do zápisu platformy vrazíš další platformy?

Engin (11:11 AM) :

to co sem teď napsal :-)

Romeo (11:12 AM) :

ne blbě

Romeo (11:12 AM) :

vznikne platforma

Engin (11:12 AM) :

přeci platforma

Romeo (11:12 AM) :

zkracuje se to na platforma

Engin (11:12 AM) :

jasné

ale jak se taková platforma zapíše

Engin (11:12 AM) :

?

Romeo (11:12 AM) :

tak a jsi zase v ****** .)

Romeo (11:12 AM) :

má cenu ji zapisovat jinak než jako platformu, když ti stejně po té co to zapíšeš vznikne vždycky platforma?

Engin (11:12 AM) :

:-D

a to sem zrovna chtěl napsat jak by se mi dobře četla taková práce a psal posudek

platforma

platforma

platforma

platforma

platforma

platforma

platforma

Engin (11:13 AM) :

takže dojdeme k tomu co mě tak před 5 minutama napadlo

Engin (11:13 AM) :

že to vlastně ani nemusíme psát

Romeo (11:13 AM) :

nemusíme

Engin (11:13 AM) :

stačí, když se na tebe kouknu, a vím co si myslíš

Romeo (11:13 AM) :

prostě platforma

Engin (11:13 AM) :

platforma!

Romeo (11:13 AM) :

vem si jak by byl život jednoduchý

Engin (11:13 AM) :

joo

Engin (11:13 AM) :

zpátky pravěk

Romeo (11:13 AM) :

sice bysme se posunuly na úroveň prvoků, ale co už

Engin (11:13 AM) :

nikdo by nedostal to co chce protože všichni by dostali platformu

Romeo (11:13 AM) :

takovému prvoku stačí platforma.

Engin (11:13 AM) :

teda všichni by chtěli platformu

Engin (11:13 AM) :

tak by ji dostali

Engin (11:14 AM) :

ale každý by dostal jinou než jakou bych chtěl

Engin (11:14 AM) :

ale to je taky irelevantní, protože platforma je prostě platforma

Engin (11:14 AM) :

prostě

Engin (11:14 AM) :

platforma

Romeo (11:14 AM) :

každý by měl co by chtěl a vlastně by byli všichni spokojení

Romeo (11:14 AM) :

takový komunismus.

Engin (11:14 AM) :

nedáme to na ruprta?

Romeo (11:14 AM) :

teda platformismus

Romeo (11:14 AM) :

jsem pro napíšeš to?

Engin (11:14 AM) :

spíš nihilismus

nebo platformismus

Engin (11:14 AM) :

jenom to tam kopnem, ne? :-)

Romeo (11:14 AM) :

asi jo

Romeo (11:14 AM) :

:-)

Engin (11:14 AM) :

nadepíšem, že je to Off topic

Romeo (11:15 AM) :

ty jo to je boží my máme stejného klienta

Romeo (11:15 AM) :

teda stejnou platformu.

Engin (11:16 AM) :

žejo

Engin (11:16 AM) :

a to si furt držkoval :-)

Romeo (11:16 AM) :

nemusím ti nadávat, že jsi platforma, protože máš jinou platformu

Romeo (11:16 AM) :

vlastně musím, říct, že jsi platforma.

Romeo (11:16 AM) :

takže jsi na tom vlastně stejně :-D

Engin (11:16 AM) :

moc mi to neva

Romeo (11:16 AM) :

to sis nepolepšil

Engin (11:17 AM) :

ty seš totiž taky platforma

Romeo (11:17 AM) :

jo

Romeo (11:17 AM) :

co na to říct, třeba platforma.

Engin (11:17 AM) :

leda že bychom byli jak ve školce a říkali si, že si "platforma nejplatformovatjší"

www.zive.cz má recenzi na VS2008

Na Žívě vyšla pozitivně nabitá recenze na Visual Studio 2008

http://www.zive.cz/default.aspx?article=138579

Každopádně pro komunitu vyvojar.cz nic nového Wink

 

ruprt

Oracle developer + SQL Server

Oraclisti vychvalují novou verzi Oracle developeru. Sám ho už nějakou dobu pro databáze Oracle využívám. Jenomže novou verzi je možné použít i pro jiné databáze, mimo jiné SQL Server. Tak jsem to zkusil. Jenomže to není tak jednoduché. Chyběl nějaký driver. To mě sice trošku zklamalo, ale po troše hledání to Oraclisti nemají až tak špatně vymyšlené. Přímo na jejich stránkách je podcast http://www.oracle.com/technology/tech/migration/workbench/viewlets/sqlserverconnlauncher.html. Takže jde o to schrastit JARko s jdbc driverem pro sql server a přidat ho mezi ovladače databází třetích stran v Oracle developeru (viz podcast)

Takže do Tools/Preferences/Database/Third Party JDBC Drivers se přidá driver k sql serveru (viz příloha.)

Pokud Oracle developer nemáte a neznáte, tak vřele doporučuju http://www.oracle.com/technology/products/database/sql_developer/index.html

ruprt

Autentizace na SQL server 2005

Snažil jsem se využít windowsovou (doménovou) autentizaci na databázi SQL 2005.

Bohužel standardní funkce:

  • user_name();
  • session_user;
  • current_user;

Vždy vrací uživatele 'dbo'. Je to proto, že jsem byl v roli sysadmins. Server tak pro všechny sysadminy vrací vždy 'dbo'. Pro ostatní uživatele vrací přihlašovací jméno dle očekávání.

Funkce suser_sname( ) vrací správné přihlašovací jméno za každého počasí.

 

ruprt

Posted: 26. července 2007 12:26 by ruprt | 34 Comments
Vedeno pod:
Assembly na SQL serveru 2005 II.

Tento článek vzniká na základě jedné reakcí na můj minulý článek (Assembly na SQL Serveru I. díl)

Obsah příspěvku:

  • Jak napsat .NET assembly v C#,
  • Jak assembly registrovat na serveru,
  • Jak vytvořit funkce, procedury a triggery na SQL serveru,
  • Jak zavolat její funkce.

Vytvoření assembly

Ve VS 2005 vytvořím nový projekt typu Class Library. Zaprvé zruším namespace. Pokud bude mít assembly vlastní namespace nebudou funkce na serveru vidět (to je má vlastní zkušenost je možné že namespace mít může, každopádně mě to s ním nešlo. Třeba mě někdo opraví.;-) ) . Výsledek tedy vypadá asi takto.

 

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SqlServer.Server;

 

    public class MyClass

    {

 

    }

 

Používám namespace Microsoft.SqlServer.Server. Obsahuje atributy, které budu využívat a některé objekty, které využiju v triggerech.
Mám assembly mám třidu. Do třídy implementuju požadované funkce. Mám na výběr 3 typy:

  • Stored proceduru;
  • Funkci;
  • Trigger;

Podmínkou je, aby třída byla public, mnou implementované funkce byly public a static.

 

Implementace Stored procedur

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SqlServer.Server;

 

    public class MyClass

    {

        [SqlProcedure]

        public static void MySP()

        {

            // Nějaký suprový kód, který toho bude dělat samé suprové věci.

        }

 

    }

 

Atribut SqlProcedure označuje, že jde o SP. Tento atribut je nepovinný. Navíc může definovat jméno procedury.

 

[SqlProcedure (Name=“MySPName“)]

 

Parametry stejně jako v SQL mohou být vstupní, výstupní, nebo vstupně-výstupní.

 

        /// <summary>

        /// SP která má jeden vstupní parametr

        /// </summary>

        [SqlProcedure]

        public static void SPInput(int number)

        {

            // Nějaký suprový kód, který toho bude dělat samé suprové věci.

        }

 

        /// <summary>

        /// SP která má jeden výstupní parametr

        /// </summary>

        [SqlProcedure]

        public static void MySPOutput(out int number)

        {

            // Nějaký suprový kód, který toho bude dělat samé suprové věci.

            number = 2;

        }

 

        /// <summary>

        /// SP která má jeden vstupně-výstupní  parametr

        /// </summary>

        [SqlProcedure]

        public static void MySPInputOutput(ref int number)

        {

            // Nějaký suprový kód, který toho bude dělat samé suprové věci.

            number = 3;

        }

 

Navíc mohou SP mít návratovou hodnotu. Ale vždy musí jít o int.

 

        /// <summary>

        /// SP která s návratoným kódem

        /// </summary>

        [SqlProcedure]

        public static int MySPReturn()

        {

            // Nějaký suprový kód, který toho bude dělat samé suprové věci.

            return 4;

        }

 

Implementace funkcí

Implementace funkcí je vpodstatě stejná jako implementace stored procedur. rozdíl je v tom, že vrací nějakou hodnotu.

 

        [SqlFunction]

        public static int MyFce(int x, int y)

        {

            // Nějaký suprový kód, který toho bude dělat samé suprové věci.

            return x + y;

        }

 

Funkce má také různé další atributy jako jsou:

  • Name
  • DataAccess
  • IsDeterministic
  • IsPrecise

Více viz nápověda.

 

Implementace triggerů

U triggerů je určitý rozdíl, který vychází z povahy triggeru. Při implementaci musíte rozhodnout cíl, a událost (Target, Event), kterých se bude trigger týkat.

 

[SqlTrigger(Event = "FOR INSERT",  Target = "Table.Collumn")]

        public static void AddSomething()

        {

            SqlTriggerContext context = SqlContext.TriggerContext;

 

            if (context.TriggerAction == TriggerAction.Insert)

            {

                string blablabla = "";

 

                for (int i = 0; i < context.ColumnCount; ++i)

                {

                    blablabla += string.Format("Column number: {0} ", i);

                    blablabla += string.Format("Updated: {0} \r\n", (context.IsUpdatedColumn(i) == true) ? "True" : "False");

                }

 

                // Zobrazení, uložení nebo něco s blablabla

            }

        }

 

SqlTriggerContext umožní nahlédnutí na data. Snadno zjistíme jaká data se změnila a jak.

 

Registrace Assembly na serveru

Na registraci můžu využít GUI SQL Serveru 2005 a příkaz add assembly, každopádně jde o jednoduchý DDL příkaz. Syntaxe:

 

CREATE ASSEMBLY <NAME> FROM <path>

 

Nebo

 

CREATE ASSEMBLY <NAME> FROM <bytestream>

 

Pro náš příklad by to bylo:

 

CREATE ASSEMBLY MyAssembly FROM 'c:\MyAssebly.dll'

 

nebo

 

CREATE ASSEMBLY MyAssembly FROM 0x123456123456...

 

Přestože se druhý způsob zdá poněkud nepohodlný. díky bytestreamu je možné assembly snadno naskriptovat.

co se týče dalších možností pro DDL příkaz CREATE ASSEMBLY odkážu vás na nápovědu a na předchozí článek, kde vysvětluju rozdíly mezí oprávněními.

 

Vytvoření procedur, funkcí a triggerů na serveru

V tuto chvíli máme zkompilovanou assembly a registrovanou na serveru. Ale jak se dostaneme na její funkce? Snadno pojmenujeme si je DDL příkazy.

 

Stored procedury Sytax:

 

CREATE PROCEDURE <ProcedureName> AS

EXTERNAL NAME <AssemblyIdentifier>.<TypeName>.<MethodName>

AssemblyIdentifier je název assembly v našem případě MyAssembly

TypeName je název třídy (MyClass)

MethodName je jméno SP (Těch máme víc)

sktipr pro naše procedury bude vypadat takto:

CREATE PROCEDURE SPInput           

@number int

AS EXTERNAL NAME MyAssembly.MyClass.SpInput

 

CREATE PROCEDURE MySPOutput   

@number int OUTPUT

AS EXTERNAL NAME MyAssembly.MyClass.MySPOutput

 

CREATE PROCEDURE MyInputSPOutput      

@number int OUTPUT

AS EXTERNAL NAME MyAssembly.MyClass.MyInputSPOutput

 

-- návratový typ se nedeklaruje

CREATE PROCEDURE MySPReturn   

AS EXTERNAL NAME MyAssembly.MyClass.MyInputSPOutput

 

Funkce Syntax:

 

CREATE FUNCTION MyFce      

(

            @x int,

            @y int

)

RETURNS int

AS EXTERNAL NAME MyAssembly.MyClass.MyFce

 

Triggery Syntax:

 

CREATE TRIGGER AddSomething

ON Table.Collumn FOR INSERT

AS EXTERNAL NAME MyAssembly.MyClass. AddSomething

 

A jserm hotov. Mám assembly na serveru mám tam funkce stored procedury a triggery. Pokud mají přistupovat na nějaké systémové zdroje jako je např. filesystem musí se assembly registrovat trochu odlišně. s odlišnými právy popř. přidat další reference.  viz můj článek Assembly na SQL Serveru I. díl.

Pokud se rozhodnu vytvořit další assembly, která mou první (MyAssembly) využívá mohu na ni s klidným svědomím přidat referenci a na server ji přidat. Jenom při opětovném vytváření schématu je nutné dát pozor na pořadí registrace assembly. Assembly, která je referencována musí přijít na server první. Pokud přidáte assembly s referencí, kterou server nezná, tak vás seřve a CREATE ASSEMBLY se nepovede.

 

Volání funkcí assembly

Jsme v poslední části příspěvku. Myslím si, že nyní je využití už jasné. Pro prosté spuštění můžete využít např. GUI SQL Serveru 2005 nebo tento prostý SQL příkaz.  

 

exec MyProc

 

ruprt

Posted: 18. července 2007 11:59 by ruprt | 3 Comments
Vedeno pod: , ,
Assembly na SQL serveru 2005 I.

SQL server 2005 umožňuje využití assembly pro volání funkcí, stored procedur a triggerů.

Jeví se to jako velice výhodné pro chvíle, kdy je vám procedurální SQL úzké nebo pokud chcete provést činnost, která je v SQL nemožná. Každopádně existují určitá omezení. Vyžití assembly na SQL serveru 2005 vyžaduje tři základní kroky:

  1. Napsání a  kódu a zkompilování do assembly
  2. Nainstalování assembly na SQL server 2005
  3. Vytvoření objektu (funkce, procedury nebo triggeru) z assembly v DDL

Na databázi je nutné zapnout podporu pro CLR

Sp_configure ‘clr enabled‘, 1

GO

RECONFIGURE

GO

Databáze podporuje jenom pár vybraných knihoven, na které je možné vytvářet reference:

·         custommarshallers.dll

·         Microsoft.visualbasic.dll

·         Microsoft.visualc.dll

·         mscorlib.dll

·         system.data.dll

·         System.Data.SqlXml.dll

·         system.dll

·         system.security.dll

·         system.web.services.dll

·         system.xml.dll

·         System.Transactions

·         System.Data.OracleClient

·         System.Configuration

Pokud si s tímto seznamem nevystačíte musíte další knihovny zaregistrovat sami. 

Přiklad: Mám assembly, která vyhledává uživatele v AD. Používám referenci System.DirectoryServices.dll. Moje assembly zaregistrovat nepůjde, protože server použitou referenci nezná. Musím nejdříve zaregistrovat System.DirectoryServices.dll a pak už svou assembly, která na System.DirectoryServices odkazuje.

Při registraci assembly jsou možné tři různé sady přístupových práv:

  • Safe
  • External access
  • Unsafe

Safe - výchozí oprávnění. Je nejrestriktivnější a neumožní práci se systémovými prostředky, jako je file system, registry, síť apod.
External access - umožní práci se systémovými prostředky právě tak jak mód safe omezuje.
Unsafe - umožní neomezený přístup kamkoliv. Navíc umožní volání neřízeného kódu.

Aby bylo možné nastavit Unsafe a External access je ještě třeba zapnout Trustworthy. Ve výchozím nastavení je vypnuto

ALTER DATABASE [DB_NAME] SET trustworthy ON

 

Výhodou takového řešení je přenesení části kódu, u kterého je to žádoucí, na stranu serveru.

 

ruprt

Posted: 17. července 2007 14:30 by ruprt | 1 Comments
Vedeno pod: ,
Ideální font programátora

Po mnoha zkušenostech a prácí na různých počítačích svých i cizích, jsem nadobro vyléčený používat nějaké výraznější customizace prostředí a systému. Na ploše mám jednu z povedenějších fotek svého synka jinak mám maximum ve výchozím stavu. XP mám "modré" používám minimum vychytávek. Není pak větší problém efektivně pracovat na libovolném jiném počítači. Ale je tu jeden rozdíl. Týká se přímo programátorské práce. Mám trošku pozměněné VS spíš málo, ale přece. Pro práci potřebuju mít dostupných pár věcí, utilit a prográmků, které jsem zvyklý často používat. A už vpodstatě několik let podnikám hon na ideální programátorský font. Už delší dobu mám v oblibě jeden. Ale jaké používáte vy? Pošte komentáře odkazy apod.

5 P, které musí mít pořádný font programátora:

  • Pořádný programátorský font musí umět českou diakritiku.
  • Pořádný programátorský font musí být bezpatkový.
  • Pořádný programátorský font musí umět co nejvíce běžných velikostí.
  • Pořádný programátorský font musí mít dobře rozlišitelnou kurzívu a tučné písmo od běžného.
  • Pořádný programátorský font musí být co nejužší a nejnižší při zachování maximální čitelnosti.

V příloze se mrkněte na můj font co už delší dobu používám. Jmenuje se Bitstream Vera Sans. Vytýkám mu snad jen to, že je docela velký. Těším se na vyše komentáře.

ruprt

Rozdělení editoru VS II

Přiznám se že mě docela zaujal ohlas, jaký vzbudilo rozložení okna z kódem na 2 části. K této featurce se může vázat jedna podobná. Máte-li více otevřených souborů, stačí pravým tlačítkem myši chytit záložku jednoho a přetáhnout a pustit ji na druhém a z otevřeného menu vybrat New Vertical/Horizontal TAB a soubory se zobrazí vedle sebe. Třeba to někomu bude k něčemu dobré.

 

ENG

Posted: 3. července 2007 9:13 by ruprt | 4 Comments
Vedeno pod:
Volání .NET Assembly z C++ jinak a možná lépe

Můj předchozí příspěvek byl o postupu jak napsat v C# (resp. v .NETu) assembly, která se bude tvářit jako COM a bude volatelná z céčka nebo jiného bazmeku. Vlastně mě k komentář k příspěvku přiměl podívat se na problém ještě trošku jinak.

Tento příspěvek bude o způsobu jak zavolat .NET assembly z C++ bez jakýchkoliv COMů a nutnosti registraci assembly na cílovém počítači. Vtip spočívá ve využití C++ .NET. V C++ .NET máte jednoduchou možnost se přepínat mezi řízeným a neřízeným kódem. Takže když píšu knihovnu v C++.NET, tak výsledkem může být napůl knihovna s exportovanými funkcemi volatelnými z neřízeného kódu a napůl assembly využívající/volající .NETí kód a assembly.

Jak na to v kostce:

1) Vytvořím si nový projekt Visual C++/CLR/Class Library

2) Jsem v řízeném kódu, tak si vytvořím novou funkci např.

void Fce1( LPSTR text)

{

String ^str = gcnew String(text);

System::Console::WriteLine(str);

} 

Tato funkce dostane string jako parametr a napíše ho do konzoly. Připomínám, že tato funkce je v .NETu v řízeném kódu.
Stejně tak tu může být cokoliv jiného vč. volání jiné funkce, nebo assembly napsané např. v C#.

3) Přepnu se do neřízeného kódu a vytvořím si funkci, která bude čistě v C++

#pragma unmanaged

extern "C" LPSTR __declspec(dllexport)__cdecl Pozdrav(LPSTR text) throw(...)

{

Fce1(text);

return text;

}

Tato funkce vrátí string, který dostane, ale předtím zavolá .NETí funkci Fce1. Funkce je deklarovaná tak, aby byla použitelná z venku. Výsledkem bude knihovna mající dvě funkce:

  • Funkce Fce1 napsaná v řízeném kódu.
  • Funkce Pozdrav napsaná v neřízeném kódu.

Funkce v neřízeném kódu bude docela elegantně používat funkci v řízeném kódu. (doufám, že to není moc zamotané)

4) Teď už mi chybí jen klient v C++. Bude to jednoduchá konzolovka.

#pragma comment(lib,"CppObj.lib")

extern "C" LPSTR __declspec(dllimport)__cdecl Pozdrav(LPSTR text) ;

int _tmain(int argc, _TCHAR* argv[])

{

Pozdrav("Ahoj Vole");

return 0;

}

Naimportoval jsem libko a importoval funkci Zdarec

Co z toho plyne? Právě jsem ukázal konzolovku v C++, která řekne knihovně aby v řízeném kódu vypsala do konzoly pozdrav.
Podle toho snadno dokážu napsat C++ knihovnu, která může být volaná z neřízeného kódu, ale přitom dobře komunikuje s řízeným kódem. Snadno implementuje libovolnou .NETí funkci nebo volá další funkce z jiných assembly.

Není nutné psát žádné COMy nemusím nikde nic registrovat. Zdá se mi to teda výhodnější než řešení co jsem popisoval včera (díky za komentář Meape). Každopádně pokud máte C++ fóbii ;-), a přesto potřebujete (třeba pro někoho) napsat knihovnu volatelnou z C++, doporučuju svůj předchozí příspěvek, jak napsat COM v C#.

 

ruprt

Posted: 27. června 2007 14:48 by ruprt | 2094 Comments
Vedeno pod:
Volání .NET assembly z C++

Každý umí volat klasické knihovny knihovny dll napsané v neřízeném kódu z .NETu.  Asi bych si už těžko dokázal představit programování v .NETu bez [DllImport("name.dll")].

Ale co opačně, co když chci využít .NET z céčka? Jak dokážu z neřízeného kódu volat řízený?
Osobně mě napadá několik možností. Ale jejich implementace je v .NETu buď trochu nešikovná nebo sebou nese velké omezení; například komunikace přes TCP potřebuje oba konce "živé". Ideálním řešením by byla prostě knihovna napsaná tak, aby ji céčko dokázalo strávit.

Co takhle COM objekt?

COM v pravém slova smyslu v .NETu nenapíšu. Ale můžu napsat knihovnu, která se jako COM bude tvářit.

Jak na to? Je nutné dodržet pár zásad:

  1. Třída musí být public;
  2. Všechny vlastnosti a metody musí být deklarovány v rozhraní;
  3. Všechny události musí být deklarovány v rozhraní;
  4. Vlastnosti, metody a události musí být public;
  5. Všechny deklarované členy v rozhraních musí být označeny atributem DispId;
  6. Všechny rozhraní a třídy musí mít atribut Guid;

Samozřejmě, že může mít i jiné metody a vlastosti, ale ty, které nebudou deklarovány, nebudou v COMu viditelné. Přesto budou viditelné pro ostatní objekty .NET.

Pro generování Guid doporučuji využít utility GuidGen.exe a zvolit formát Registry Format.

COM objekt napsaný v C#:
Postup step by step: 

1) Založím si projekt ve Visual studiu a zvolím si Class Library zvolím si název CshCOMObj

2) Přidám using

using System.Runtime.InteropServices;

3) deklarace rozhraní:

[Guid("1E98368B-7F2E-432f-BFB5-52BD968F906D")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface CsCOM_Interface
{

[DispId(1)]

bool Ahoj(string text);

}

4) Deklarace rozhraní pro události (v mém příkladě žádné nejsou):
	[Guid("FE733CA4-5CC3-424c-A6B1-797BD8569E46"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface CsCOM_Events
{
}
5) Implementace třídy s implementovaným rozhraním:
	[Guid("60701DA6-33D7-4a22-B2C9-FE4E3003A29A"),

ClassInterface(ClassInterfaceType.None),

ComSourceInterfaces(typeof(CsCOM_Events))]

[ProgId("NSCshCOMObj.CsCOM_Class")]

public class CsCOM_Class : CsCOM_Interface

{

public CsCOM_Class()

{

}

#region CsCOM_Interface Members

public bool Ahoj(string text)

{

Console.WriteLine(text);

return true;

}

#endregion

}

Tato třída bude poměrně tupá bude mít jednu jedinou metodu, která do konzoly napíše text, který obrží jako parametr a vždycky vrátí true.
Metoda Ahoj je deklarována v rozhraní.
Tím končí implementace v C#. Všimněte si označení [ProgId("NSCshCOMObj.CsCOM_Class")]. Tím označím, že třídu najde COM v namespace CshCOMObj. (Když jde o namespace, přidává se prefix NS; ve skutečnosti půjde o namespace "CshCOMObj", bez NS.) Za tečkou "CsCOM_Class" je název třídy, pod kterým ji COM najde.

6) Dalším krokem je nastavení COM Interop projektu

Ve vlastnostech projektu v sekci build je nutné zatrhnout Register for COM interop. Znamená to, že pro assemby se vytvoří wrapper volatelný z neřízeného kódu.

7) Poslední krok je nastavení silného názvu pro assembly. (Strong named assembly)

Ve vlastnostech projektu v sekci signing se musí vygenerovat klíč pro podepsání assembly.
Pozn.: Pokud se používá VS 2003, musí se vygenerovat klíče ručně pomocí utility sn.exe, soubor s klíčem přihrát k projektu a v AssemblyInfo.cs na něho přidat odkaz.

8) No a úplně poslední krok je registrování assembly do systému. Využije se utilita RegAsm.exe.

RegAsm.exe /tlb:CshCOMObj.tlb /codebase /verbose CshCOMObj.dll

Klient napsaný v C++:
Ve zkratce napíšu primitivního klienta v C++, abych dokázal, že to funguje.

1) Založím konzolovku v C++;

2) provede se import tlb souboru (který VS samo vygeneruje, když je zatrhnuté register for COM interop);

3) zavolání .NETí třídy.


#import "C:\CshCOMObj.tlb"

int _tmain(int argc, _TCHAR* argv[])

{

CoInitialize(NULL);

CshCOMObj::CsCOM_InterfacePtr pTest ( __uuidof(CshCOMObj::CsCOM_Class));

bool bX = pTest->Ahoj(L"Nazdar světe");

return 0;

}

A je to. Podle této kuchařky by neměl být problém napsat prakticky cokoliv. Já se chystám napsat rozhraní pro tisky z céčka. Pro tisky budu využívat local reporty a zobrazovat je v reportvieweru.

 ruprt

Posted: 26. června 2007 13:01 by ruprt | 3 Comments
Vedeno pod: ,
řízení vývoje

Omlouvám se všem, kteří čekali, že se něco dozví, že budou zklamáni, protože jde o příspěvek přesně opačného tipu.

Rád bych se dozvěděl něco od vás.

 Spousta čtenářů a jistě většina komunity pracuje v různým firmách různých velikostí a na různým pozicích. Proto mám dotaz.

  • Jakým způsobem řídíte vývoj?
  • Máte nějaký systém na evidenci člověkodnů?
  • Něco co vám dá přehled o vytíženosti vývoje?
  • Na plánování lidských zdrojů?  
  • Jak to děláte?

Pište prosím komentáře.

Outlining vs VS05 Express

Jenom poznámka. Možná jste si všimli, že v express verzích (vyjma WebDeveloper) zmizela z menu volba pro Outlining. Pro ty z nás, kterým tam hrozně moc chybí sbalování všeho, je dobrá zpráva, že stále fungují klávesové zkratky:

Ctrl+M+O - sbalí všechno

Ctrl+M+M - sba/rozbalí aktuální

Ctrl+M+L - přerozbalí všechno (no lepší to vyzkoušet než číst).

 ENG

Generování dokumentace VS2005 přes NDoc

Tak jsem po dlouhé době pohledal, či se nepohl projekt NDoc pro VS2005 a FW2.0 a ejhle. Po trochu boji to funguje. Takže jak na to?

 Na stránkách sourceForge se jako klasicky dá najít několik projektů (binaries nebo src). Binaries bohužel obsahují kompilační chyby. My se zaměříme na naše překompilované sources s některými sekcemi zdrojového kódu, které budeme muset opravit. Takže:

 1) Potřebujeme src od projektu NDoc 2005 BetaRelease, které nalezneme na

http://sourceforge.net/project/showfiles.php?group_id=163095&package_id=184303&release_id=411019

odkazem NDoc2005BetaSrc.zip.

2) Rozbalíme, otevřeme ve studiu a je třeba provést změnu v souboru .\Msdn\MsdnHtmlUtilitiesV20.cs záměnou obsahu metody InitializeNamespace() za tento kód:

        /// <summary>
        /// Initialize namespace dictionary
        /// </summary>
        public static void InitializeNamespaces(Project project)
        {
            // If we don't have namespaces list yet, go through each referenced assembly,
            // load the assembly, get the types, then cache the namespaces for all public types.
            if (namespaces.Count == 0)
            {
                foreach (AssemblySlashDoc doc in project.AssemblySlashDocs)
                {
                    //
                    string strDllFullPath = doc.Assembly.Path;
                    string strDllPath = strDllFullPath.Substring(
                        0, strDllFullPath.LastIndexOf(@"\") + 1);
                    //

                    Assembly theAssembly = Assembly.LoadFrom(doc.Assembly);
                    AssemblyName[] assemblies = theAssembly.GetReferencedAssemblies();

                    foreach (AssemblyName an in assemblies)
                    {
                        //Assembly assembly = Assembly.LoadWithPartialName(an.Name);
                        Assembly assembly = null;
                        try
                        {
                            assembly = Assembly.LoadFrom(strDllPath + an.Name + ".dll");
                        }

                        catch (Exception ex)
                        {
                            try
                            {
                                assembly = Assembly.Load(an.FullName);
                            }

                            catch (Exception ex1)
                            {
                                continue;
                            }
                        }

                        if (assembly == null)
                        {
                            throw new System.IO.FileNotFoundException(
                                String.Concat(
                                    "Unable to locate the referenced Assembly ", an.Name));
                        }

                        Type[] assemblyTypes = assembly.GetTypes();

                        foreach (Type type in assemblyTypes)
                        {
                            if (type.IsPublic)
                            {
                                namespaces[type.Namespace] = 
                                    type.Namespace.Replace('.', '_') + '_';
                                namespaces[type.Namespace.Replace(".", "")] = 
                                    type.Namespace.Replace('.', '_') + '_';
                            }
                        }
                    }
                }
            }
        }

        (zdroj : http://geekswithblogs.net/SudheersBlog/archive/2006/07/24/86146.aspx)

3) Dalším problém je, že zdroje (xslt, css, aj. soubory) jsou definovány relativně vzhledem ke kompilovatelné verzi.  Proto funkčnost samotných zkompilových souborů je třeba udělat 2 věci (ve zdrojových souborech upravit string zdroje dat, a do složky s výstupem přidat složky se šablonami.

Funkční verzi jsem upravil pouze pro výstup MSDN (pro mě jediný potřebný - zatím):

3a) v projektu MSDN do souboru StyleSheetCollection.cs přidat definici

#define RELEASE_RESOURCES

a následně v metodě LoadStyleSheets nahradit celou sekci #if NO_RESOURCES ... #endif za například toto:

#if RELEASE_RESOURCES
         string resourceBase = "file://" + Path.GetFullPath(
            Path.Combine(System.Windows.Forms.Application.StartupPath, @"Msdn\xslt"));
#else
#if NO_RESOURCES
	string resourceBase = "file://" + Path.GetFullPath(
            Path.Combine(
                System.Windows.Forms.Application.StartupPath, 
                @"..\..\..\Documenter\Msdn\xslt") );
#else
         string resourceBase = "NDoc.Documenter.Msdn.xslt";
#endif
#endif

3b) Ve výstupní složce vytvoříme novou složku nazvanou "MSDN" a vykopírujeme do ní z projektu MSDN podsložky CSS, Images, OnlineFiles, OnlineTemplates a xslt.

4) Zkompilujeme, spustíme a projekt by měl fungovat.

ENG

 Zdroje:

http://www.wwwcoder.com/main/parentid/263/site/6246/68/default.aspx

http://geekswithblogs.net/SudheersBlog/archive/2006/07/24/86146.aspx

http://sourceforge.net/tracker/index.php?func=detail&aid=1479548&group_id=163095&atid=826379

http://forums.microsoft.com/msdn/showpost.aspx?postid=111392&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=1

 

 

PS:

Při rozcházení NDoc05 se nejčastěji objevují 2 základní chyby:

  • Could not find a part of the path <nějaká cesta>\Msdn\xslt\namespace.xslt'. - je způsobenou pevnou cestou určenou při kompilaci balíku a vyskytuje se pouze u binárních verzí. U verzí vycházejíccíh ze zdrojových souborů (náš případ) se při překompilování cesta nahradí správnou a chyba nenastane;
  • Falied to load Assembly <název>- je zase chyba, která se vyskytuje při nenahrazení metody InitializeNamespaces() uvedené v bodě 2.
Default Printing

Dnes jsem potřeboval zobrazit název tiskárny, která se bude využívat pro tisk protokolů v aplikaci.

Prokoly se měli tisknout na výchozí tiskárnu ve windows (default). Takový tisk je vlastně ještě jednoduší než když se tiskárna specifikuje. Aspoň tehdy, když se neuvažuje využití PrintDialogu. Protože se o nic nestarám. Nezajímá mě název tiskárny, nestarám se o zobrazení výběru nebo specifikaci nastavení.

Problémje, když potřebuju zjistit, zda má systém instalovánu aspoň jednu tiskárnu? A která to je? Pokud existuje alepoň jedna tiskárna vždy existuje nějaká výchozí tiskárna. A pokud existuje nějaká výchozí pak je defaultně v PrintDocumentu.

//Default tiskárna
System.Drawing.Printing.PrintDocument PD;
PD = new System.Drawing.Printing.PrintDocument();
string DefaultPrinterName = PD.PrinterSettings.PrinterName;

 

//Všechny ostatní
foreach (string fPrinter in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
    System.Diagnostics.Debug.WriteLine("Název tiskárny: " + fPrinter);
}

No a pokud není žádná tiskárna instalována, tak žádná tiskárna v PrintDocumentu není. Resp. Kolekce InstalledPrinters je prázdná.

 

ruprt

Posted: 4. června 2007 14:34 by ruprt | 46 Comments
Vedeno pod: ,
Vyvojar.cz na prodej!