На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Как использовать с# в качестве скрипта?
    Никак не могу понять.
    Мы можем написать набор фнкций на c#, загнать их в библиотеку. Потом просто подцепить их к своему сишному проекту и использовать.
    А какие библиотеки подцепить, чтобы я пиасал на c# в текстовом редакторе, без компиляции? А в своем сишном проекте читал бы этот скрипт (без пересборки проекта). А скрип на c# при этом вызывал бы мои функции из проекта.
    Должен жк быть в .NET какой-то встроенный интерпритатор скриптов!
      ИМХО, C# - это не скрипт. Поэтому и интерпретировать его, как скрипт не удасться. Ведь C++ тоже не интерпретируется, и у тебя, надеюсь, по этому поводу вопросов не возникает :)
        Почему тогда говорится, что c# скриптовый язык? А .Net обеспечивает поддержку скриптового языка c#?
          Цитата DarkKo, 29.08.03, 12:09:10
          Почему тогда говорится, что c# скриптовый язык? А .Net обеспечивает поддержку скриптового языка c#?

          Где говорится?  Цитату из MSDN -  в студию
            Цитату я не нашел. Я это вычитал скорее всего в интернете. Почему я решил, что он может использоваться как скрипт - потому что при сравнивании быстродействия скриптовых языков в сравнении учавствовал c# (хотя всетаки это ни о чем не говорит).
            Ввиду понимания своей неправоты, переформулирую вопрос.
            Вот к примеру, есть скриптовый язык lua. Я подшиваю люшные библиотеки в проекту. Регистрирую какие-то функции, которые связаны и с чтением скрипта и с моим кодом. Ну и при чтении скрипта (в рантайме), просто вызываются мои функции, какие мне надо, с параметрами, которые я задаю в скрипте (ну и логика там есть какая-то). Хочу получить такой же эффект при использовании c#.
            Хорошо, допустим написанный код на c# будет еще компилироваться в байт код или какую-нибудь библиотеку. Могу я пересобирать c# ресурсы при рантайме моей программы (моя программа на си++), и "читать" их в рантайме. И как это сделать?
            Если я так могу сделать, то c#  - выглядит как скриптовый язык, и может его легко заменить. Ну и по бысмтродействию он гораздо быстрее. Поэтому и привлекателен.
              Понимаешь, в .NET есть JScrpit.NET, но и он по большому счету компилируемый язык, утилита jsc.exe. Но в принципе  его можно компилить на лету. Почитай вот эту ветку, может тебе поможет: http://www.rsdn.ru/Forum/?mid=67746
                Чуваки не спорьте, C# это не скрипт. Но есть рантайм компиляция!

                Т.е. делаем интерфейсную библиотеку, делаем шаблончик на C#, типа (это из моего проЭкта, обработка MSWord шаблонов с C# вставками)
                ExpandedWrap disabled
                  <br>using System;<br>using Globalz;//Всякие примочки<br>using WordExportHelper;//В помощь юзерам<br><br>namespace Protocols {<br>      public class Worker {<br>            ///// GLOBAL-DECLARATIONS<br><br>            private GlobalDS.ProtocolsRow CP,CurrentProtocol;<br>            private Word.Application Application;//"Эмуляция" VB<br>            private Word.Selection Selection;<br><br>            private Firm Applicant;<br>            private Production[] Production;<br><br>            private object False=false;//передача параметров в Word только по ссылке (ref) - :(<br>            private object True=true;<br><br>            private object skip=Type.Missing;<br><br>            public Worker(GlobalDS.ProtocolsRow prow, Word.Application app){<br>                  CP=CurrentProtocol=prow;<br>                  Application=app;<br>                  Selection=app.Selection;<br><br>                  GlobalDS.ProductionRow[] prs=prow.GetProductionRows();<br>                  Production=new Production[prs.Length];<br>                  for(int i=0;i<prs.Length;i++){<br>                        Production[i]=new Production(prs[i]);<br>                  }<br>                  Applicant=new Firm(CP.FirmsRow);<br>            }<br>            public void PrintGOSTs(string delimiter){<br>//...<br>            }<br>            private void PrintAllProduction(){<br>//...<br>            }<br>            private void Print(params object[] list){<br>                  if(list.Length==0)return;<br>                  if(list[0].GetType()==typeof(string)){<br>                        object[] prm=new object[list.Length-1];<br>                        Array.Copy(list,1,prm,0,list.Length-1);<br>                        Application.Selection.Text=String.Format((string)list[0],prm);<br>                  }else{<br>                        string s="";<br>                        foreach(object o in list){<br>                              s+=o.ToString();<br>                        }<br>                        Application.Selection.Text=s;<br>                  }<br>            }<br>            private void GoTo(int label){<br>                  object rt=new bool(),rf=new bool();<br>                  rt=true;rf=false;<br>                  object str;<br>                  object es="";<br>                  object of=Word.WdFindWrap.wdFindContinue;<br>                  Word.Find fnd=Application.Selection.Find;<br>                  fnd.ClearFormatting();<br>                  str="[!<@@"+label+">]";                  <br>                  Application.ActiveWindow.ActivePane.View.SeekView=Word.WdSeekView.wdSeekMainDocument;<br>                  if(!fnd.Execute(ref str,ref rf,ref rf,ref rf,ref rf,ref rf,ref rt,ref of,ref rf,ref es,ref rf,ref rf,ref rf,ref rf,ref rf)){<br>                        Application.ActiveWindow.ActivePane.View.SeekView=Word.WdSeekView.wdSeekPrimaryFooter;<br>                        if(!fnd.Execute(ref str,ref rf,ref rf,ref rf,ref rf,ref rf,ref rt,ref of,ref rf,ref es,ref rf,ref rf,ref rf,ref rf,ref rf)){<br>                              Application.ActiveWindow.ActivePane.View.SeekView=Word.WdSeekView.wdSeekPrimaryHeader;<br>                              fnd.Execute(ref str,ref rf,ref rf,ref rf,ref rf,ref rf,ref rt,ref of,ref rf,ref es,ref rf,ref rf,ref rf,ref rf,ref rf);<br>                        }<br>                  }<br>            }<br>            public void ParseL3(){<br>                  ///// WORKER-TEXT<br>                  Application.ActiveWindow.ActivePane.View.SeekView=Word.WdSeekView.wdSeekMainDocument;<br>            }<br>      }<br>}<br>


                Потом пишется у себя нечто такое:

                ExpandedWrap disabled
                  <br>using System;<br>using System.CodeDom.Compiler;<br>using System.IO;<br>using Globalz; //это моя interface assembly<br>using System.Collections;<br>using System.Data;<br>using System.Text.RegularExpressions;<br><br>namespace Output<br>{<br>      public class Output<br>      {<br>            public Output()<br>            {<br>            }<br>//СОБСТВЕННО МЕТОД ДЛЯ ВЫВОДА<br>//GlobalDS - dataset type<br>//Globals.GDS - dataset instance<br>//ns WordExportHelper - вторая часть интерфейсной библиотеки<br>            public  void O(GlobalDS.ProtocolsRow prr,object filename,object newname)<br>            {                  WordExportHelper.Production.resolved.Clear();<br><br>//шаблончик<br>                  StreamReader rdr=new StreamReader("out-tpl.cs",System.Text.Encoding.Default);<br>                  string program=rdr.ReadToEnd();<br>                  rdr.Close();<br>                  <br>                  Word.ApplicationClass wa=new Word.ApplicationClass();<br>                  object rt=new bool(),rf=new bool();<br>                  rt=true;rf=false;<br>                  object str;<br>                  object es="";<br>                  object of=Word.WdOpenFormat.wdOpenFormatAuto;<br>                  object enc=Microsoft.Office.Core.MsoEncoding.msoEncodingCyrillicAutoDetect;<br>                  object dir=Word.WdDocumentDirection.wdLeftToRight;<br>                  try <br>                  {<br>/// :)<br>                        Word.Document doc=wa.Documents.Open(ref filename,ref rf,ref rt,ref rf,ref es,ref es,ref rf,ref es,ref es,ref of,ref enc,ref rt,ref rf,ref dir,ref rt);<br>                        Word.Find fnd=wa.Selection.Find;<br>                        fnd.ClearFormatting();<br><br>//В таких скобках в документе ворда вставляются C# вставки<br>                        str="\\[\\<*\\>\\]";<br>                        object fw=Word.WdFindWrap.wdFindContinue;<br>                        fldno=0;<br>                        object ep=Type.Missing;<br>//Первый проход парсера - вытаскивание C# вставок, замена из на метки (туда потом будет вставлятся вывод)<br>                        while(fnd.Execute(ref str,ref rf,ref rf,ref rt,ref rf,ref rf,ref rt,ref fw,ref rf,ref es,ref rf,ref rf,ref rf,ref rf,ref rf)) {<br>                              Word.Selection sel=wa.Selection;<br>                              ParseL1(sel);<br>                        }<br>                        doc.ActiveWindow.ActivePane.View.SeekView=Word.WdSeekView.wdSeekPrimaryFooter;<br>                        while(fnd.Execute(ref str,ref rf,ref rf,ref rt,ref rf,ref rf,ref rt,ref fw,ref rf,ref es,ref rf,ref rf,ref rf,ref rf,ref rf)) {<br>                              Word.Selection sel=wa.Selection;<br>                              ParseL1(sel);<br>                        }<br>                        doc.ActiveWindow.ActivePane.View.SeekView=Word.WdSeekView.wdSeekPrimaryHeader;<br>                        while(fnd.Execute(ref str,ref rf,ref rf,ref rt,ref rf,ref rf,ref rt,ref fw,ref rf,ref es,ref rf,ref rf,ref rf,ref rf,ref rf)) {<br>                              Word.Selection sel=wa.Selection;<br>                              ParseL1(sel);<br>                        }<br><br>//Понеслась - пишем прогу :)<br>//Заменяем строки в шаблоне проги (не word документе) на то что вытащили за первый проход<br>                        int ll=program.IndexOf("///// WORKER-TEXT");<br>                        program=program.Insert(ll,"///// WORKER-TEXT\n"+WorkerText);<br>                        ll=program.IndexOf("///// GLOBAL-DECLARATIONS");<br>                        program=program.Insert(ll,"///// GLOBAL-DECLARATIONS\n"+GlobalDeclarations);<br><br>//Записываем файлик<br>                        StreamWriter wr=new StreamWriter("out-done.cs",false,System.Text.Encoding.Default);<br>                        wr.Write(program);<br>                        wr.Close();<br><br>//А теперь компилим....<br>                        Microsoft.CSharp.CSharpCodeProvider ccp=new Microsoft.CSharp.CSharpCodeProvider();<br>                        ICodeCompiler cc=ccp.CreateCompiler();<br>                        CompilerParameters cp=new CompilerParameters(new string[]{"Globalz.dll","System.dll","Interop.Word.dll","Interop.VBIDE.dll","Interop.Microsoft.Office.Core.dll","System.Data.dll","System.XML.dll"});<br><br>//Компилим<br>                        CompilerResults cr=cc.CompileAssemblyFromSource(cp,program);<br>                        <br>//Проверяем ошибки<br>                        if(cr.Errors.Count>0){<br>                              Console.WriteLine("Г-Г-Г-Г-Г-Глюк!!! - проверь файл out-done.cs!");<br>                              for(int i=0;i<cr.Errors.Count;i++){<br>                                    Console.WriteLine("{0}:{1} {2}",cr.Errors[i].Line,cr.Errors[i].Column,cr.Errors[i].ErrorText);<br>                              }<br>                              es=Type.Missing;<br>                              wa.Quit(ref rf,ref es,ref es);<br>                              return;<br>                        }<br>//ВсЁ , можно использовать<br><br>//Получаем тип из откомпиленой assembly<br>                        Type t=cr.CompiledAssembly.GetType("Protocols.Worker");<br>//Создаём его instance<br>                        object o=Activator.CreateInstance(t,new object[]{prr,wa});<br>                        try{<br>//И вызываем метод - работник<br>                              t.GetMethod("ParseL3").Invoke(o,new object[]{});<br>                        }catch(Exception ex){<br>                              Console.WriteLine(ex.ToString());<br>                        }<br>//ВсЁЁЁЁЁЁЁ, закрываем, завершаем<br>                        of=Word.WdUnits.wdStory;<br>                        wa.Selection.HomeKey(ref of,ref rf);<br><br>                        of=Word.WdSaveFormat.wdFormatDocument;<br>                        enc=Microsoft.Office.Core.MsoEncoding.msoEncodingUTF8;<br>                        dir=Type.Missing;<br>                        doc.SaveAs(ref newname,ref of,ref rf,ref es,ref rf,ref es,ref rf,ref rf,ref rt,ref rf,ref rf,ref enc,ref rf,ref rf,ref dir,ref rf);<br>                        of=Word.WdOriginalFormat.wdWordDocument;<br>                  }finally {<br>                        wa.Visible=true;<br>                  }<br>            }<br><br><br>            private string GlobalDeclarations;<br>            private string WorkerText;<br>            private int fldno=0;<br>            private void ParseL1(Word.Selection cs){<br>                  if(cs.Text.Length<4)return;<br>                  string s=cs.Text.Substring(2,cs.Text.Length-4);<br>                  if(String.Compare(s,0,"declare",0,7,true)==0){<br>                        GlobalDeclarations+="private "+s.Substring(7)+"\n";<br>                        cs.Text="";<br>                  }else{<br>                        WorkerText+="GoTo("+fldno+");\n"+s+";\n";<br>                        cs.Text="[!<@@"+(fldno++)+">]";<br>                  }<br>            }<br><br>      }<br>}<br>
                  2kl Спасибо. Помогло. По крайней мере теперь у меня есть подход к этой проблеме. Теперь я сам понимаю больше чего я хочу. :)
                  2andrey Скажи, сколько у тебя занимала рантайм компиляция (по времени), или ты замеров таких не делал?

                  Сейчас я пытаюсь организовать такой подход: написать на c# интерфейс и загрузить его как COM объект. Только вот у меня функция CoCreateInstance возвращает заначение очень интересное:      
                            0x80070002 The system cannot find the file specified.
                  И это после того как все файлы подгружены. Что за ошибка такая?
                  Вот кусок кода (считаю, что библиотеку sharp.tlb сделал правильно)

                  SimpleScriptEngine * SSE_p;// = NULL;

                             #import <mscorlib.tlb> raw_interfaces_only
                             #import "sharp.tlb" no_namespace named_guids  // это библиотека на c#
                  ...
                  ...
                  SimpleScriptEngine * SSE_p = NULL;
                  CoInitialize(NULL);
                  HRESULT hr = CoCreateInstance(
                  CLSID_ScriptEng,  // идентификато класса, из библиотеки берется
                  NULL,
                  CLSCTX_INPROC_SERVER,
                  IID_SimpleScriptEngine,// идентификатор интерфейса, тоже из библиотеки
                  (LPVOID *) (& SSE_p) // а это должна получиться ссылка на зарегистрированный интерфес
                  );
                    Замеров не делал, но точно (на глаз) могу сказать что работа небыстрая, хотя намного быстрее чем работа с Word через COM. Соотношение около 1:10.

                    Выполнение функции Output.O занимает около 1-2 секунд, если Word уже загружен и около 10 иначе. P-IV-1.8G, 512M RAM, Word XP, .NET fx 1.1, Windows XP
                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0306 ]   [ 17 queries used ]   [ Generated: 23.04.24, 22:39 GMT ]